我已经创建了一个下一个js 14.2.3应用程序并且我有graphql api端点(**我用stackOverflow的localhost替换了它)并且我正在使用“@apollo/client”:“^3.10.3”, "graphql": "^16.8.1",用于获取数据。我创建了一个产品页面路径“pages/products”。
import { useQuery, gql } from '@apollo/client';
import { initializeApollo } from '../lib/apollo-client';
const PRODUCTS_QUERY = gql`
query Products {
products(first: 10, channel: "default-channel") {
edges {
node {
id
name
}
}
}
}`;
function Products() {
const apolloClient = initializeApollo();
const { data, loading, error } = useQuery(PRODUCTS_QUERY, {
client: apolloClient,
});
if (loading) return <p>Loading...</p>;
if (error) return <p>Error: {error.message}</p>;
return (
<div>
<h1>Products</h1>
<ul>
{data && data.products.edges.map(({ node }) => (
<li key={node.id}>{node.name}</li>
))}
</ul>
</div>
);}
export default Products;
我创建了一个 apollo-client,js 文件
代码- 从 'react' 导入 { useMemo } ; 从 '@apollo/client' 导入 { ApolloClient, HttpLink, InMemoryCache };
let apolloClient;
function createApolloClient() {
return new ApolloClient({
ssrMode: typeof window === 'undefined',
link: new HttpLink({
uri: 'http://localhost:8000/graphql/',
}),
cache: new InMemoryCache(),
});}
export function initializeApollo(initialState = null) {
const _apolloClient = apolloClient ?? createApolloClient();
// If your page has Next.js data fetching methods that use Apollo Client, the initial
state
// gets hydrated here
if (initialState) {
_apolloClient.cache.restore(initialState);
}
// For SSG and SSR always create a new Apollo Client
if (typeof window === 'undefined') return _apolloClient;
// Create the Apollo Client once in the client
if (!apolloClient) apolloClient = _apolloClient;
return _apolloClient;
}
export function useApollo(initialState) {
const store = useMemo(() => initializeApollo(initialState), [initialState]);
return store;
}
所以当我路由 http://localhost:3000/pages/products 时
我认为这是因为
<Products />
组件当前呈现为 服务器组件。并且上下文不适用于服务器组件。
有两种解决方法:
是通过在
"use client"
之上添加pages/products
来使该组件成为客户端。
重写组件,直接使用apollo客户端,不依赖useQuery hook。 这里是一篇很好的文章,解释了如何做到这一点。
粗略的例子:
import { gql } from '@apollo/client';
import { initializeApollo } from '../lib/apollo-client';
const PRODUCTS_QUERY = gql`
query Products {
products(first: 10, channel: "default-channel") {
edges {
node {
id
name
}
}
}
}`;
async function Products() {
const apolloClient = initializeApollo();
const { data } = await apolloClient.query({
query: PRODUCTS_QUERY,
context: {
}
});
return (
<div>
<h1>Products</h1>
<ul>
{data?.products?.edges?.map(({ node }) => (
<li key={node.id}>{node.name}</li>
))}
</ul>
</div>
);
}
export default Products;