伺服器端渲染
使用 Next.js 進行伺服器端渲染
RTK Query 支援使用 Next.js 進行伺服器端渲染 (SSR),方法是結合 重新整理 和 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
選項設定重新水化- 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())
以確保沒有流氓計時器仍在執行。
為了避免在靜態網站產生 (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()))
等待所有查詢完成