NextJS 13.4(App Router)中Redux无法保存状态求助
问题分析与解决方案
核心问题
你的Home组件是服务器组件(async组件默认是服务器组件),直接在服务器组件中调用store.dispatch只会修改服务器端的Redux Store实例,而客户端的Redux Store是完全独立的,因此客户端无法获取到这个状态,导致看起来“状态无法保存”。
另外你的dataSlice代码存在语法错误:reducers对象末尾缺失闭合大括号,这也会影响Redux的正常工作。
修复步骤
1. 修复dataSlice的语法错误
修改src/redux/dataSlice.js,补全缺失的大括号:
import { createSlice } from "@reduxjs/toolkit"; const dataSlice = createSlice({ name: "data", initialState: { data: [], price: 0, tax: 0, }, reducers: { fetchData: (state, action) => { console.log(action.payload); state.data = action.payload; }, }, // 补全这个闭合大括号 }); export const { fetchData } = dataSlice.actions; export default dataSlice.reducer;
2. 将状态分发逻辑移到客户端组件
有两种可选方案:
方案一:服务器端获取数据,客户端组件分发状态(推荐,保留服务器渲染优势)
创建一个专门的客户端组件负责将服务器获取的数据存入Redux:
// src/components/ClientDataLoader.jsx "use client"; import { useEffect } from "react"; import { useDispatch } from "react-redux"; import { fetchData } from "@/redux/dataSlice"; export default function ClientDataLoader({ initialData }) { const dispatch = useDispatch(); useEffect(() => { dispatch(fetchData(initialData)); }, [dispatch, initialData]); return null; }
修改src/app/page.jsx,服务器端获取数据后传递给客户端组件:
import styles from "@/styles/page.module.css"; import ClientDataLoader from "@/components/ClientDataLoader"; import Counter from "@/components/counter"; const Home = async () => { const req = await fetch("https://jsonplaceholder.typicode.com/todos"); const data = await req.json(); console.log(data); return ( <> <ClientDataLoader initialData={data} /> Sample </> ); }; export default Home;
方案二:将Home组件改为客户端组件
如果不需要服务器端渲染数据,可以直接把Home改成客户端组件,在组件内完成数据获取和状态分发:
// src/app/page.jsx "use client"; import styles from "@/styles/page.module.css"; import { useDispatch } from "react-redux"; import { fetchData } from "@/redux/dataSlice"; import Counter from "@/components/counter"; import { useEffect } from "react"; const Home = () => { const dispatch = useDispatch(); useEffect(() => { const loadData = async () => { const req = await fetch("https://jsonplaceholder.typicode.com/todos"); const data = await req.json(); console.log(data); dispatch(fetchData(data)); }; loadData(); }, [dispatch]); return ( <> Sample </> ); }; export default Home;
原理说明
- Next.js App Router中,async组件默认是服务器组件,运行在服务器端;Redux Provider是客户端组件,客户端的Store实例仅存在于浏览器环境中。
- 服务器端的Store和客户端的Store是完全独立的两个实例,因此服务器端的
dispatch无法影响客户端状态。 - 必须在客户端组件中使用
useDispatch钩子来分发action,才能修改客户端的Redux Store,确保状态能被客户端组件获取和保存。
内容的提问来源于stack exchange,提问作者Shanu Flash
相关产品推荐
相关产品推荐

