You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何设置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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 06:06:07