You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js中next-redux-wrapper与Redux Toolkit、RTK Query集成及服务端数据获取问题

解决Next.js中getServerSideProps预取RTK Query数据的问题

核心问题分析

你遇到的store未定义是因为没通过next-redux-wrapper的包装器在getServerSideProps中获取服务端store实例,另外RTK Query的initiate返回Promise,必须用unwrap()等待请求完成,才能确保数据预取完毕。

步骤1:配置适配next-redux-wrapper的store

首先你的store要基于configureStore创建,导出makeStore函数供next-redux-wrapper使用,同时集成RTK Query的API切片:

// store.js
import { configureStore } from '@reduxjs/toolkit'
import { createWrapper } from 'next-redux-wrapper'
import { listsApi } from './services/listsApi' // 你的RTK Query API切片
import useReducer from './reducers/useReducer' // 自定义reducer

export const makeStore = () => {
  return configureStore({
    reducer: {
      useReducer,
      [listsApi.reducerPath]: listsApi.reducer,
    },
    middleware: (getDefaultMiddleware) =>
      getDefaultMiddleware().concat(listsApi.middleware),
  })
}

export const wrapper = createWrapper(makeStore)

步骤2:修改页面的getServerSideProps

用wrapper.getServerSideProps包装你的函数,这样就能拿到服务端store实例,然后预取两个查询并等待完成:

import { wrapper } from '../store' // 导入store包装器
import { listsApi } from '../services/listsApi' // 导入API切片

const ToDoComponent = dynamic(() => import("../components/ToDoComponent"), {
  loading: () => <NextNProgress />,
})

const ToDo = ({ darkmode }) => {
  const username = useSelector((state) => state.useReducer.username)
  const { isMobileState } = useIsMobile()
  
  // 直接用服务端预取的暗色模式数据
  setNextTheme(darkmode)
  useRedirect()

  return (
    <>
      <ToDoComponent isMobileState={isMobileState} darkmode={darkmode} />
    </>
  )
}

export const getServerSideProps = wrapper.getServerSideProps(async (context) => {
  const { store } = context
  const username = "hardcoded username" // 这里可从context.req取cookie或context.query取参数,替换硬编码值

  // 预取用户暗色模式数据,等待请求完成
  const darkModeResult = await store.dispatch(listsApi.endpoints.getUserDarkMode.initiate(username)).unwrap()
  
  // 预取用户列表数据,等待请求完成
  await store.dispatch(listsApi.endpoints.getUserLists.initiate(username)).unwrap()

  // 将预取的暗色模式数据传递给组件
  return {
    props: {
      darkmode: darkModeResult,
    },
  }
})

export default ToDo

步骤3:客户端组件复用预取数据

在ToDoComponent中使用RTK Query的hooks时,会自动识别服务端预取的数据,不会重复发起请求:

// ToDoComponent.js
import { useGetUserListsQuery } from '../services/listsApi'

const ToDoComponent = ({ isMobileState, darkmode }) => {
  const username = useSelector((state) => state.useReducer.username)
  // 直接复用服务端预取的用户列表数据
  const { data: userLists } = useGetUserListsQuery(username)

  return (
    // 组件渲染内容
  )
}

关键注意事项

  • 必须用wrapper.getServerSideProps包装函数,才能获取服务端store实例
  • RTK Query的initiate返回ThunkAction,必须调用unwrap()等待请求完成,否则可能数据未加载就返回页面
  • 若username不是硬编码,可从context.req.cookies读取登录态,或从context.query获取URL参数

内容的提问来源于stack exchange,提问作者Lucas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 19:33:07