如何设置Redux store初始状态 解决首次加载读取state属性undefined问题
问题原因
- reducer初始值设置错误:你当前给
votdReducer设置的默认state是空对象{},首次渲染还未触发任何action时,state.votd就是空对象,你尝试从空对象中解构votd属性时拿到的是undefined,读取undefined的bible属性自然会抛出错误。 - 初始state结构嵌套错误:你定义的
votdFromStorage默认返回的是{ votd: { bible: "", ... } }结构,又将该值赋值给全局initialState的votd字段,如果本地存储中存的是直接的经文对象,会导致最终state结构和组件预期结构不匹配,同样会触发空值报错。
解决方案
步骤1:修正reducer初始值
直接将votd切片的完整初始结构定义在reducer的默认参数中,同时统一处理localStorage逻辑,避免结构冲突:
// 处理本地存储逻辑,返回完整的votd切片初始状态 const getInitialVotdState = () => { const storedVotd = localStorage.getItem("votd"); return { loading: false, error: null, votd: storedVotd ? JSON.parse(storedVotd) : { bible: "", verse: [], passage: "", chapter: "" } } } // 给reducer传入正确的初始状态 export const votdReducer = (state = getInitialVotdState(), action) => { switch (action.type) { case VOTD_REQUEST: return { ...state, loading: true }; case VOTD_SUCCESS: // 接口请求成功后同步更新本地存储 localStorage.setItem("votd", JSON.stringify(action.payload)); return { loading: false, error: null, votd: action.payload }; case VOTD_FAIL: return { ...state, loading: false, error: action.payload }; default: return state; } };
步骤2:删除冗余的全局初始状态
删掉你在store中全局initialState里定义的votd字段,combineReducers会自动使用reducer内置的初始状态,避免多层赋值导致结构冲突。
可选兜底方案
如果不想修改现有状态逻辑,可以直接在组件解构时加默认值兜底,避免空值报错:
const dispatch = useDispatch(); const { votd: { bible, passage, verse, chapter } = {}, // 给votd对象加空对象兜底 loading, } = useSelector((state) => state.votd || {}); // 给整个votd切片加空对象兜底 useEffect(() => { dispatch({ type: VOTD_REQUEST }); dispatch(verseOfTheDay()); }, [dispatch]);
内容的提问来源于stack exchange,提问作者Austin Howard
相关产品推荐
相关产品推荐

