服务器端渲染
使用 Next.js 进行服务器端渲染
RTK Query 通过 Next.js 中的 重新水化 与 next-redux-wrapper 结合,支持服务器端渲染 (SSR)。
工作流程如下
设置
next-redux-wrapper
在
getStaticProps
或getServerSideProps
中- 通过
initiate
操作预取所有查询,例如store.dispatch(api.endpoints.getPokemonByName.initiate(name))
- 使用
await Promise.all(dispatch(api.util.getRunningQueriesThunk()))
等待每个查询完成
- 通过
在
createApi
调用中,使用extractRehydrationInfo
选项配置重新水合- TypeScript
- JavaScript
next-redux-wrapper 重新水合示例import type { Action, PayloadAction } from '@reduxjs/toolkit'
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'
import { HYDRATE } from 'next-redux-wrapper'
type RootState = any // normally inferred from state
function isHydrateAction(action: Action): action is PayloadAction<RootState> {
return action.type === HYDRATE
}
export const api = createApi({
baseQuery: fetchBaseQuery({ baseUrl: '/' }),
extractRehydrationInfo(action, { reducerPath }): any {
if (isHydrateAction(action)) {
return action.payload[reducerPath]
}
},
endpoints: (build) => ({
// omitted
}),
})next-redux-wrapper 重新水合示例import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'
import { HYDRATE } from 'next-redux-wrapper'
function isHydrateAction(action) {
return action.type === HYDRATE
}
export const api = createApi({
baseQuery: fetchBaseQuery({ baseUrl: '/' }),
extractRehydrationInfo(action, { reducerPath }) {
if (isHydrateAction(action)) {
return action.payload[reducerPath]
}
},
endpoints: (build) => ({
// omitted
}),
})
一个使用 next.js
的示例仓库可以 在这里 获取。
虽然不预计出现内存泄漏,但一旦渲染结果发送到客户端并且商店从内存中删除,您可能希望也调用 store.dispatch(api.util.resetApiState())
以确保没有 rogue 定时器仍在运行。
为了避免在静态站点生成 (SSG) 中提供陈旧的数据,您可能希望将 refetchOnMountOrArgChange
设置为一个合理的值,例如 900(秒),以便在访问数据时重新获取数据,如果自页面生成以来已经过去了这么长时间。
其他地方的服务器端渲染
如果您没有使用 next.js
,并且上面的示例无法适应您的 SSR 框架,则可以使用一个标记为 unstable__
的方法来支持您需要在渲染期间执行异步代码而不是在效果中安全执行的 SSR 场景。这与使用 getDataFromTree
与 Apollo 的方法类似。
工作流程如下
创建一个在渲染期间执行异步工作的
createApi
版本- TypeScript
- JavaScript
import {
buildCreateApi,
coreModule,
reactHooksModule,
} from '@reduxjs/toolkit/query/react'
const createApi = buildCreateApi(
coreModule(),
reactHooksModule({ unstable__sideEffectsInRender: true })
)import {
buildCreateApi,
coreModule,
reactHooksModule,
} from '@reduxjs/toolkit/query/react'
const createApi = buildCreateApi(
coreModule(),
reactHooksModule({ unstable__sideEffectsInRender: true })
)在调用
const api = createApi({...})
时使用您自定义的createApi
在执行下一个渲染周期之前,使用
await Promise.all(dispatch(api.util.getRunningQueriesThunk()))
等待所有查询完成