React-Redux中如何向数组添加元素并返回新数组?
解决React-Redux中Reducer添加数组元素的问题
咱们先拆解下你代码里的核心问题:
[...user]的错误:user是一个对象,用展开运算符...把对象放到数组里,得到的是对象所有键名组成的数组(比如["id", "homeFloor", "avatarUrl", "login"]),而非把user作为单个元素加入现有用户数组,这就是你得到不符合预期数组的原因。push()的错误:数组的push()方法会直接修改原数组(违反Redux中state不可变的核心原则),而且它返回的是新数组的长度(数字类型),不是你需要的新数组,所以state会被错误设置成数字。
下面给你两种靠谱的实现方案:
方案一:组件中生成新数组,传递给Action
保持你现有Reducer的逻辑(直接替换users为传入的payload),修改点击处理函数即可:
userClickHandler() { const { id, homeFloor, avatarUrl, login } = this.props; const newUser = { id, homeFloor, avatarUrl, login }; // 基于现有users数组创建新数组,追加新用户 const updatedUsers = [...this.props.event.users, newUser]; // 把新数组传给action this.props.changeEventUsers(updatedUsers); }
核心是用展开运算符...复制原数组的所有元素,再把新用户追加到末尾,生成全新的数组——既不修改原state,又得到了包含新元素的目标数组。
方案二:Reducer中处理添加逻辑(更推荐)
如果想让Reducer统一负责state的更新逻辑(组件不用关心state结构,更符合Redux职责划分),可以这样修改:
1. 更新Reducer逻辑
让Reducer接收新用户对象,自动生成包含新用户的新数组:
case CHANGE_EVENT_USERS: // 复制原state,再更新users数组:原数组展开 + 新用户 return { ...state, users: [...state.users, payload] };
2. 简化组件中的点击处理
现在只需要传递新用户对象给action即可:
userClickHandler() { const { id, homeFloor, avatarUrl, login } = this.props; const newUser = { id, homeFloor, avatarUrl, login }; // 直接传新用户对象 this.props.changeEventUsers(newUser); }
重要提醒
- Redux state不可变是底线:永远不要直接修改原state数组(比如
push、splice、pop这类方法),必须通过复制原数组生成新数组的方式更新。 - 除了展开运算符,你也可以用
Array.concat()实现相同效果(比如state.users.concat(payload)),两种写法任选其一就行。
内容的提问来源于stack exchange,提问作者Rami Chasygov
相关产品推荐
相关产品推荐

