为什么React的state hook更新单个成员属性时会修改所有对象元素?
问题原因
1. 应用对象引用全局共享
你在初始化成员数据时,仅生成了一次apps数组,所有Member实例的apps属性都指向同一个数组,其中的每个Application实例都是全局唯一的。当你修改任意成员下某个应用的isSelected属性时,本质是修改了公共的Application实例,因此所有成员的对应应用状态都会同步变化。
2. State更新方式不符合规范
你的members是数组类型,但代码中使用{...members}将数组转为普通对象操作,同时直接修改了原state中的对象属性,违反了React状态更新的不可变原则,可能引发额外的状态更新异常。
修复方案
- 每个成员实例化时,单独生成专属的应用列表,避免引用共享:
const membersObject = teamMembers.map((member, i) => { // 每个成员独立创建一套Application实例,互不干扰 const memberApps = appsFromBase.map((app, idx) => new Application(idx, false, app)); return new Member(i, member.name, member.email, memberApps); });
- 修正事件处理逻辑,遵循不可变原则更新状态:
const handleChoosenApp = (app, member_i) => { const _id = app.idApp; if (_id === 'btn-all-app') return; setMembers(prevMembers => { return prevMembers.map((member, idx) => { // 非目标成员直接返回 if (idx !== member_i) return member; // 拷贝目标成员的应用列表 const newApps = member.apps.map((appItem, appIdx) => { // 非目标应用直接返回 if (appIdx !== _id) return appItem; // 拷贝应用实例后修改状态,不改动原对象 const newApp = new Application(appItem.idApp, appItem.isSelected, appItem.appName); newApp.toggleSelected(); return newApp; }); // 返回新的成员对象 return { ...member, apps: newApps }; }) }) }
内容的提问来源于stack exchange,提问作者Taras Potsykailo
相关产品推荐
相关产品推荐

