Redux状态更新时先出现null再加载真实数据的问题解决求助
问题解决:Redux Posts数组出现null值的原因及修复方案
核心问题定位
1. Reducer分支未中断执行
你的Post Reducer中,每个case语句后都没有添加break,导致执行完UPLOAD_START后会继续触发UPLOAD_SUCCESS的逻辑——此时action.data不存在,被push进数组后就变成了null。
2. 异步操作时序混乱
SharePost组件中,uploadImage是异步dispatch,但你直接紧接着调用uploadPost,图片上传未完成就提交帖子,可能导致后端返回的帖子数据异常。
3. 帖子获取逻辑未在Reducer中处理
你补充的RETRIEVING_SUCCESS动作没有在Reducer中定义对应的处理分支,若后端返回数据包含null,也会直接混入posts数组。
修复步骤
步骤1:修复Reducer分支中断问题
给每个case添加break,并补充RETRIEVING相关动作的处理:
import { enableAllPlugins, produce } from 'immer'; enableAllPlugins(); const initialState = { posts: [], loading: false, error: false, uploading: false, }; const postReducer = produce((draftstate, action = {}) => { switch (action.type) { case 'UPLOAD_START': draftstate.loading = true; draftstate.error = false; break; // 新增中断 case 'UPLOAD_SUCCESS': draftstate.posts.push(action.data); draftstate.uploading = false; draftstate.error = false; break; // 新增中断 case 'UPLOAD_FAIL': draftstate.uploading = false; draftstate.error = true; break; // 新增中断 case 'RETRIEVING_START': draftstate.loading = true; break; case 'RETRIEVING_SUCCESS': // 直接替换数组,避免重复数据或混入null draftstate.posts = action.data.filter(post => post !== null); draftstate.loading = false; break; case 'RETRIEVING_FAIL': draftstate.loading = false; draftstate.error = true; break; default: return draftstate; } }, initialState); export default postReducer;
步骤2:修正异步操作时序
等待图片上传完成后再提交帖子,避免数据异常:
const handleSubmit = async (e) => { e.preventDefault(); const newPost = { userId: user._id, desc: desc.current.value, }; if (image) { const data = new FormData(); const filename = Date.now() + image.name; data.append("name", filename); data.append("file", image); newPost.image = filename; try { await dispatch(uploadImage(data)); // 等待图片上传完成 } catch (error) { console.log(error); return; // 上传失败则终止后续操作 } } dispatch(uploadPost(newPost)); reset(); };
步骤3:添加数据有效性校验
在上传帖子的action中,确保后端返回的数据有效:
export const uploadPost = (data) => async (dispatch) => { dispatch({ type: 'UPLOAD_START' }); try { const newPost = await UploadApi.uploadPost(data); console.log('new post before', newPost); // 仅当数据有效时才触发成功动作 if (newPost?.data) { dispatch({ type: 'UPLOAD_SUCCESS', data: newPost.data }); } else { throw new Error('获取到无效的帖子数据'); } } catch (error) { console.log(error); dispatch({ type: 'UPLOAD_FAIL' }); } };
总结
最直接的原因是Reducer分支未添加break,导致无关逻辑被错误执行。配合异步时序修正和数据校验,即可彻底解决posts数组出现null的问题。
内容的提问来源于stack exchange,提问作者Johnson Durant
相关产品推荐
相关产品推荐

