You need to enable JavaScript to run this app. 仅使用Redux(未用react-redux)时useEffect中dispatch后cards报map错误
优惠活动
大模型
产品
解决方案
定价
更多

仅使用Redux(未用react-redux)时useEffect中dispatch后cards报map错误

问题排查与修复

核心问题:reducer缺少默认返回值,导致store初始化失败

Redux要求reducer在未匹配到对应action类型时,必须返回传入的原有state,否则会把store的全局state直接覆盖为undefined。
你的reducer逻辑里,default分支只写了break,函数执行结束后没有返回值,最终返回undefined。
而createStore初始化时,会自动dispatch一个内部的初始化action,这个action永远匹配不上SET_CARDS类型,会直接走入default分支,把你一开始传入的预定义state(带空cards数组的那个对象)直接覆盖为undefined。
这就能解释你观察到的差异:

  • 在store.js里手动dispatch动作时,reducer拿到的当前state是undefined,执行{...undefined, cards: 生成的卡牌数组}是合法的JS语法,最终返回一个带cards属性的新对象,所以这时候取cards能正常拿到数组,看起来功能正常
  • 但组件首次渲染时,store.getState()本身就是undefined,你写的store.getState().cards?.map的可选链只做了cards存在性的判断,挡不住“读取undefined对象上的cards属性”的报错,最终抛出无法对cards调用map的错误。

修复代码:

const reducer = (state, action) => {
  switch (action.type) {
    case "SET_CARDS":
      return {
        ...state,
        cards: action.payload.initCards(),
      };
    default:
      // 未匹配的action直接返回原state,不能让reducer返回undefined
      return state;
  }
};

次要问题:可选链的保护逻辑位置错误

你目前的可选链写法:

{store.getState().cards?.map((card) => <div>{card}</div>)}

只判断了cards字段是否存在,没判断store.getState()本身是否有效,安全的写法应该把可选链提前到读取getState结果的位置:

{store.getState()?.cards?.map((card) => <div>{card}</div>)}

额外规范提醒

  • 按照Redux的设计规范,action的payload应该存放可序列化的纯数据,不建议把initCards这种带逻辑的生成函数存在action对象里。你可以提前把卡牌数组生成好,直接把数组作为payload传入action,避免把非序列化数据存在store的动作流里。
  • 现在setCards对象是写在Game组件函数体内的,虽然空依赖的useEffect只会在首次渲染时执行一次dispatch,不会直接导致功能失效,但每次组件重渲染都会重新创建这个大对象,可以把它挪到组件外部定义,减少不必要的内存消耗。

内容的提问来源于stack exchange,提问作者morh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.04 11:24:01