如何在React路由跳转时持久化Redux状态避免帖子数据丢失
问题原因
- 帖子列表渲染用的是组件本地状态
newPosts,组件卸载(返回上一页)后本地状态会重置,你虽然把数据存到了Redux,但没有在组件挂载时从Redux读取数据回填到本地状态,也没有直接用Redux的数据做渲染 setNewPosts是异步更新,你刚执行setNewPosts就dispatchnewPosts,此时dispatch的是更新前的旧数组,Redux里根本没存到最新的帖子postsSlice的初始值设置错误,你要存的是帖子数组,但是初始值设成了空字符串"",类型不匹配- 渲染列表时读取的是本地的
newPosts,而不是Redux中存储的loadPosts,Redux存储的数据没有被实际使用
修复方案
- 先修改
postsslice.js的初始值为数组:
import { createSlice } from "@reduxjs/toolkit"; const postsSlice = createSlice({ name: "posts", initialState: [], // 从空字符串改成空数组 reducers: { savePosts: (state, action) => action.payload } }); export default postsSlice
- 修改CRUD页面(MainScreen)的逻辑,直接使用Redux存储的帖子数据做渲染,不再单独维护本地的帖子状态,同时修正提交逻辑:
- 删掉本地
newPosts相关的状态声明 - 提交时先构造新的帖子数组再dispatch到Redux
- 渲染列表时改用从Redux取到的
loadPosts遍历
修改后的核心代码片段:
function MainScreen() { const dispatch = useDispatch(); const user = useSelector((state) => state.user) const loadPosts = useSelector((state) => state.loadPosts) // 直接用Redux的帖子数据 const [title, setTitle] = useState(""); const [content, setContent] = useState(""); // 删掉原来的const [newPosts, setNewPosts] = useState([]) const [buttonGreyOut, setButtonGreyOut] = useState("#cccccc"); // 其他useEffect等逻辑不变... const handleSubmitSendPost = (e) => { e.preventDefault(); // 先构造新的帖子数组,不用依赖异步的setState const updatedPosts = [...loadPosts, {title, content}]; dispatch(postsSlice.actions.savePosts(updatedPosts)) setTitle('') setContent('') }; // 其他逻辑不变... // 渲染时把原来的newPosts.map改成loadPosts.map return ( // 其他布局不变... {loadPosts.map((post) => ( // 帖子渲染内容不变... ))} ) }
修改后帖子数据统一存在Redux里,无论怎么切换页面,只要不刷新浏览器,数据都不会丢失,组件每次挂载都会从Redux读取最新的帖子列表渲染。
内容的提问来源于stack exchange,提问作者Heitor Kenzou
相关产品推荐
相关产品推荐

