服务器端渲染
使用 Next.js 进行服务器端渲染
RTK Query 支持通过 Next.js 进行服务器端渲染 (SSR),这是通过 rehydration 与 next-redux-wrapper 的组合实现的。
工作流程如下:
-
设置
next-redux-wrapper
-
在
getStaticProps
或getServerSideProps
中:- 通过
initiate
动作预获取所有查询,例如store.dispatch(api.endpoints.getPokemonByName.initiate(name))
- 使用
await Promise.all(dispatch(api.util.getRunningQueriesThunk()))
等待每个查询完成
- 通过
-
在你的
createApi
调用中,使用extractRehydrationInfo
选项配置 rehydration:// 代码块元数据 标题="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; // 通常从状态推断
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) => ({
// 省略
}),
})
一个使用 next.js
的示例仓库可以在 这里 找到。
虽然不预期会有内存泄漏,但一旦渲染被发送到客户端并且存储正在从内存中移除,你可能也希望调用 store.dispatch(api.util.resetApiState())
以确保没有遗留的定时器在运行。
为了避免在静态站点生成 (SSG) 中提供过时的数据,你 可能希望将 refetchOnMountOrArgChange
设置为一个合理的值,例如 900 (秒),以便在访问数据时如果页面生成已经过去这么长时间,允许数据被重新获取。
在其他地方进行服务器端渲染
如果你不使用 next.js
,并且上面的示例不能适应你的 SSR 框架,一个标记为 unstable__
的方法可以支持你在渲染期间而不是在 effect 中安全地执行异步代码的 SSR 场景。这与使用 getDataFromTree
与 Apollo 的方法类似。
工作流程如下:
-
创建一个在渲染期间执行异步工作的
createApi
版本: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()))
等待所有查询完成