Next.js 如何在React组件外访问store:getServerSideProps中获取状态
问题根因
useSelector 是React Hook,只能在React函数组件或自定义Hook内部调用,getServerSideProps 是Next.js在服务端独立运行的函数,不在React组件生命周期范围内,本身也没有React上下文环境,所以直接调用Hook必然报错。
另外需要注意核心逻辑误区:服务端运行的getServerSideProps和客户端浏览器的运行环境完全隔离,默认无法直接访问客户端store中存储的状态。
解决方案
分两种适用场景处理:
场景1:需要在服务端获取store中的全量/公共状态
这种场景需要每次请求在getServerSideProps内单独创建独立的服务端store实例,避免多请求状态串扰。
步骤1:改造store配置为工厂模式
不要导出单例store,而是导出一个每次调用都生成新store实例的方法,示例用Redux Toolkit实现:
// store.js import { configureStore } from '@reduxjs/toolkit' import productReducer from './productSlice' // 每次调用都返回新的store实例,适配服务端多请求场景 export const createStore = () => { return configureStore({ reducer: { productList: productReducer } }) }
步骤2:在getServerSideProps中初始化store并取值
import { createStore } from './store' import { fetchProductList } from './productSlice' export async function getServerSideProps() { // 1. 为当前请求单独创建服务端store实例 const store = createStore() // 2. 按需dispatch获取数据的action,拿到你需要的productList状态 await store.dispatch(fetchProductList()) // 3. 从store中取到需要的状态 const { products } = store.getState().productList // 注意原代码的props需要传入对象,否则组件无法正确接收 return { props: { products } } }
场景2:需要用到客户端store存储的用户个性化状态
客户端store的个性化状态如果要传递到服务端,需要提前存在cookie中,在getServerSideProps的请求上下文中读取cookie后初始化store:
export async function getServerSideProps(context) { const store = createStore() // 从请求头拿到cookie里存储的个性化状态 const productFilter = context.req.cookies.productFilter || {} // dispatch对应action把cookie中的状态存入服务端store store.dispatch(setFilter(productFilter)) // 再获取需要的商品列表 const { products } = store.getState().productList return { props: { products } } }
可选优化:不需要SSR的状态直接在组件内取
如果你要的productList不需要服务端渲染注入,完全可以删掉getServerSideProps里的相关逻辑,直接在Home组件内调用useSelector取值即可,写法和普通React项目完全一致。
内容的提问来源于stack exchange,提问作者abood alwa7sh
相关产品推荐
相关产品推荐

