Next.js useQuery是否在服务器端渲染上运行?
我是Nextjs新手,对Nextjs中的客户端渲染和服务器端渲染有一些疑问Next.js useQuery是否在服务器端渲染上运行?,next.js,apollo,apollo-client,Next.js,Apollo,Apollo Client,我是Nextjs新手,对Nextjs中的客户端渲染和服务器端渲染有一些疑问 我知道有两种方法可以在Nextjs上获取数据。其中之一是使用useQueryhook,但只能在React组件函数上调用。这是否意味着它仅在从客户端呈现页面时运行 我读了一篇关于如何将apolloClient连接到Nextjs的帖子。据说 始终为SSR创建一个新的apolloClient实例,并仅为CSR创建一个apolloClient实例 下面是示例代码 export function initializeApoll
useQuery
hook,但只能在React组件函数上调用。这是否意味着它仅在从客户端呈现页面时运行apolloClient
连接到Nextjs的帖子。据说apolloClient
实例,并仅为CSR创建一个apolloClient
实例
下面是示例代码
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) {
// Get existing cache, loaded during client side data fetching
const existingCache = _apolloClient.extract();
// Restore the cache using the data passed from
// getStaticProps/getServerSideProps combined with the existing cached data
_apolloClient.cache.restore({ ...existingCache, ...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;
}
有人能解释一下吗?如果下一篇JS中的问题很愚蠢,我很抱歉:
- -服务器端呈现-getServerSideProps
- -生成静态站点-GetStaticPath/getStaticProps
- CSR-客户端渲染-其他一切
\u app.js
上并使用。在其他客户端页面上,您将使用调用单个全局实例的钩子
服务器端(SSR)函数getStaticProps或getServerSideProps无权访问Apollo的客户端实例、Next的客户端实例或其他服务器端函数。因此,您必须在使用GetStaticPath、getStaticProps或getServerSideProps并需要访问Apollo客户端的每个页面上定义Apollo连接,否则服务器端调用将无法使用该连接
因为,第一个问题是它们只能在顶层(客户端)调用,所以不能在服务器端函数中使用它们。不,您不能在下一个SSR或SSG函数中运行useQuery
您提供的示例是保持缓存同步,并且是。下面是一个简化的例子,更符合官方文件的内容
graphqlClient.js
import { ApolloClient, HttpLink, InMemoryCache } from '@apollo/client';
// Used server and client side - can't use react hooks
export const graphqlClient = new ApolloClient({
cache: new InMemoryCache(),
link: new HttpLink({
uri: 'YOUR_GQL_ENDPOINT',
}),
ssrMode: typeof window === 'undefined',
});
_app.js-所有客户端页面都使用的单个实例,因为它包装了整个应用程序
import graphqlClient from 'my/path/graphqlClient';
const App = ({ Component, pageProps }) => {
const client = graphqlClient();
return (
<ApolloProvider client={client}>
<Component {...pageProps} />
</ApolloProvider>
);
};
每个使用SSR或SSG函数并需要访问Apollo的页面都必须实例化Apollo的新实例
SSG
固态继电器
谢谢你的回答。它非常详细,帮助很大。还有一个问题,每当我们创建Apollo客户端实例时,它也会创建Apollo缓存、Apollo链接等等,对吗?服务器端不必对它做任何事情(Apollo缓存、Apollo链接)?Apollo将在创建客户端时添加您定义的任何内容。在上面的示例中,定义了缓存和链接,并可用于服务器和客户端。但是,服务器端调用只能访问其一个客户端及其当前状态。因此,SSR缓存本质上是空的,或者只包含在调用时在同一SSR函数中进行的Apollo调用。有很多方法可以将服务器端调用配置为彼此更加同步,但这本身就是一篇完整的文章,并不总是需要的——特别是在SSG站点中。
import { gql, useQuery } from '@apollo/client';
import graphqlClient from 'my/path/graphqlClient';
const About = () => {
const { data } = useQuery(YOUR_QUERY); // uses your single instance defined in _app.js
const { data } = await client.query({query: YOUR_QUERY});
return (
...
)
}
import graphqlClient from 'my/path/graphqlClient';
//does not have access to _app.js or client and must define new Apollo Client instance
export const getStaticProps = async () => {
const client = graphqlClient();//
const { data } = await client.query({query: YOUR_QUERY});
};
export const getStaticPaths = async () => {
const client = graphqlClient();
const { data } = await client.query({query: YOUR_QUERY});
};
import graphqlClient from 'my/path/graphqlClient';
//does not have access to _app.js or client and must define new Apollo Client instance
export const getServerSideProps = async () => {
const client = graphqlClient();
const { data } = await client.query({query: YOUR_QUERY});
};