服务器端渲染是否使用 useQuery 运行?
Does useQuery run on server-side rendering?
我是 Nextjs 的新手,对 Nextjs 中的客户端渲染和服务器端渲染有一些疑问
- 我看到有两种方法可以在 Nextjs 上获取数据。其中之一是使用
useQuery
钩子,但只能在 React 组件函数上调用。这是否意味着从客户端呈现页面时仅运行
- 我读了 post 关于如何将
apolloClient
连接到 Nextjs 的文章。据说
always create a new instance of apolloClient
for SSR and only create one instance of apolloClient
for CSR
这是示例代码
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 中:
请务必注意,SSG 函数是 运行 服务器端的。
在客户端,您只想创建一个 Apollo Client 的全局实例。创建 Apollo Client 的多个实例将使与客户端保持同步变得具有挑战性。这个困难是因为Apollo Cache,Apollo Link等,都会存储在不同的Apollo Client实例中
在下一步中,通常将 Apollo Client 的全局实例放在页面上 _app.js
并使用调用您的单个全局实例的 Apollo Provider. On the other client-side pages, you'd use the useQuery
挂钩。
服务器端 (SSR) 函数 getStaticProps
或 getServerSideProps
无权访问 Apollo 的客户端实例、Next 的客户端实例或其他服务器端函数。因此,您必须在每个使用 getStaticPaths
、getStaticProps
或 getServerSideProps
并且需要访问 Apollo 客户端的页面上定义您的 Apollo 连接,否则服务器将无法访问它-边调用。
因为第一个 rule of hooks 是它们只能在顶层(客户端)调用,所以不能在服务器端函数中使用它们。不,您不能在 Next SSR 或 SSG 函数中 运行 useQuery
。
您提供的示例是保持缓存同步并且 outdated in how it is defining the client。这是一个更符合官方文档的简化示例。
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>
);
};
每个 page/component 客户端都可以使用 useQuery 挂钩,因为 Apollo Client 将应用程序包装在 _app.js
中
客户端查询
import { gql, useQuery } from '@apollo/client';
const About = () => {
const { data } = useQuery(YOUR_QUERY); // uses your single instance defined in _app.js
return (
...
)
}
每个使用 SSR 或 SSG 功能并需要访问 Apollo 的页面都必须实例化一个新的 Apollo 实例。
SSG
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});
};
SSR
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});
};
最后,为了简化您可以使用的东西 graphql-code-generator to auto-generate Apollo query, mutation, etc. hooks (and types for TS users) as well as server-side compatible query and mutation functions for Next.js。
我是 Nextjs 的新手,对 Nextjs 中的客户端渲染和服务器端渲染有一些疑问
- 我看到有两种方法可以在 Nextjs 上获取数据。其中之一是使用
useQuery
钩子,但只能在 React 组件函数上调用。这是否意味着从客户端呈现页面时仅运行 - 我读了 post 关于如何将
apolloClient
连接到 Nextjs 的文章。据说
always create a new instance of
apolloClient
for SSR and only create one instance ofapolloClient
for CSR
这是示例代码
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 中:
请务必注意,SSG 函数是 运行 服务器端的。
在客户端,您只想创建一个 Apollo Client 的全局实例。创建 Apollo Client 的多个实例将使与客户端保持同步变得具有挑战性。这个困难是因为Apollo Cache,Apollo Link等,都会存储在不同的Apollo Client实例中
在下一步中,通常将 Apollo Client 的全局实例放在页面上 _app.js
并使用调用您的单个全局实例的 Apollo Provider. On the other client-side pages, you'd use the useQuery
挂钩。
服务器端 (SSR) 函数 getStaticProps
或 getServerSideProps
无权访问 Apollo 的客户端实例、Next 的客户端实例或其他服务器端函数。因此,您必须在每个使用 getStaticPaths
、getStaticProps
或 getServerSideProps
并且需要访问 Apollo 客户端的页面上定义您的 Apollo 连接,否则服务器将无法访问它-边调用。
因为第一个 rule of hooks 是它们只能在顶层(客户端)调用,所以不能在服务器端函数中使用它们。不,您不能在 Next SSR 或 SSG 函数中 运行 useQuery
。
您提供的示例是保持缓存同步并且 outdated in how it is defining the client。这是一个更符合官方文档的简化示例。
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>
);
};
每个 page/component 客户端都可以使用 useQuery 挂钩,因为 Apollo Client 将应用程序包装在 _app.js
客户端查询
import { gql, useQuery } from '@apollo/client';
const About = () => {
const { data } = useQuery(YOUR_QUERY); // uses your single instance defined in _app.js
return (
...
)
}
每个使用 SSR 或 SSG 功能并需要访问 Apollo 的页面都必须实例化一个新的 Apollo 实例。
SSG
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});
};
SSR
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});
};
最后,为了简化您可以使用的东西 graphql-code-generator to auto-generate Apollo query, mutation, etc. hooks (and types for TS users) as well as server-side compatible query and mutation functions for Next.js。