Redux Toolkit:entityAdapter与自定义回调更新状态的异常问题
问题原因及解决办法
核心原因:状态结构不匹配
createEntityAdapter 是Redux用来管理多实体集合(比如用户列表)的工具,它生成的默认状态结构是这样的:
{ ids: [], // 存储实体ID的数组 entities: {} // 存储实体的键值对,key是ID,value是实体对象 }
而你的初始状态是一个包含user字段的对象:
const initialState = { user: Cookies.get('user') ? JSON.parse(Cookies.get('user')) : null, };
当你调用usersAdapter.addOne时,它只会更新状态里的ids和entities字段,但你的状态里根本没有这两个字段,原来的user字段完全没被修改。所以useSelector(state => state.user)自然还是null,直到刷新页面时,初始状态从Cookies重新读取到用户数据,才会显示正常。
解决办法
办法1:如果非要用createEntityAdapter,调整状态结构
把初始状态改成adapter的标准结构,同时保留当前用户的字段:
// 先创建adapter const usersAdapter = createEntityAdapter(); // 初始化状态,基于adapter的默认结构扩展currentUser字段 const initialState = usersAdapter.getInitialState({ currentUser: Cookies.get('user') ? JSON.parse(Cookies.get('user')) : null, }); // 在slice的extraReducers里,既要添加实体到集合,也要更新currentUser const userSlice = createSlice({ name: 'user', initialState, reducers: {}, extraReducers(builder) { builder.addCase(loginUser.fulfilled, (state, action) => { usersAdapter.addOne(state, action.payload); state.currentUser = action.payload; }); }, }); // 首页用useSelector取currentUser const currentUser = useSelector(state => state.user.currentUser);
办法2:放弃用createEntityAdapter(更适合单用户场景)
createEntityAdapter本来就是为多实体集合设计的,单用户登录状态完全没必要用它,直接用你原来的自定义回调更新state.user的方式就足够简单可靠。
内容的提问来源于stack exchange,提问作者andyoee
相关产品推荐
相关产品推荐

