React使用Redux Saga拉取用户数据后无法正常渲染问题求助
错误汇总
- Saga请求参数与返回值处理错误
- service调用返回的是api的完整响应对象,你没有取
data字段,直接把响应对象当用户数组处理 - 构造了符合
IUsers结构的usersList但没有传入success action,反而传了原始response,导致reducer拿到的payload结构不符合预期
- service调用返回的是api的完整响应对象,你没有取
- Reducer不满足纯函数要求
- 直接用
push修改原state的users数组,违反Redux不可变更新原则,不会触发state更新 - 没有返回新的state对象,reducer执行后state不会变更
- 直接用
- 组件调用逻辑错误
useEffect依赖项为空,只会在组件首次挂载时执行一次,此时Saga请求还没返回,拿到的是初始空数据,后续Redux的users更新不会触发重新赋值- 混淆了
getUsers的作用:你mapDispatch里的getUsers是触发请求的action creator,不是从Redux拿到的用户数据,你应该用mapState里注入的users属性来遍历
- Action触发逻辑缺失
- 组件里没有调用
getUsers.trigger(查询参数)来发起Saga请求,压根没走拉取用户的流程
- 组件里没有调用
修正代码
1. Saga代码修正
function* getAllUsersMentions(action) { try { // 取api返回的data字段,才是后端返回的用户数组 const response = yield call(viewPageService.getAllUserMentions, action.payload); // 构造符合IUsers结构的 payload const usersList = { users: response.data }; // 传入正确的结构给success action yield put(getAllUserRoutine.success(usersList)); toastr.success('Success', 'get user'); } catch (error) { yield put(getAllUserRoutine.failure(error?.message())); } }
2. Reducer代码修正
[getAllUserRoutine.SUCCESS]: (state, { payload }: PayloadAction<IUsers>) => { // 返回全新的state对象,不可变更新 return { ...state, // 如果是每次查询覆盖原有用户列表,直接写 users: payload.users users: [...state.users, ...payload.users] } }
3. 组件内逻辑修正
// 组件挂载时触发拉取用户的请求 useEffect(() => { // 替换成实际要传的查询参数query props.getUsers.trigger('你的查询参数'); }, [props.getUsers]); // 监听Redux传入的users变化,同步到本地state useEffect(() => { // props.users才是Redux里存的用户数组,不是getUsers setUsers(props.users.map(user => ({ display: `@${user.nickname}`, id: user.id }))); // 依赖项加上props.users,Redux数据更新会触发重新赋值 }, [props.users]);
额外排查点
- 确认
viewPostSagas里已经监听了getAllUserRoutine.TRIGGER动作,对应执行getAllUsersMentions方法 - 用Redux DevTools检查ACTION是否正常触发、SUCCESS动作的payload结构是否符合预期、state是否正常更新
- 如果不需要本地存一份users的state,可以直接把
props.users转换后传给react-mentions组件,不需要多走一层useState
内容的提问来源于stack exchange,提问作者kiker
相关产品推荐
相关产品推荐

