【发布时间】:2021-06-04 11:16:57
【问题描述】:
我有一个多选项卡视图,我通过全局状态控制数据,并通过 useContext(连同 setState 更新程序函数)传递。
结构类似
globalState: {
company: {
list: [
[{name: ..., ...}, {field1: ..., ... }],
[{name: ..., ...}, {field1: ..., ... }],
...
]
},
...
}
我在第一个选项卡中有一个表格,其中每一行显示每个内部列表数组 (globalState.company.list[X][0]) 的第一个对象中的详细信息,并且有几个复选框可以切换每个内部列表中第二个对象中的字段数组(globalState.company.list[X][1])。
我遇到的问题是,当我选中特定字段的复选框时,所有公司都将该字段设置为该值之前我在来自复选框本身。
这里是创建复选框和处理程序的所有相关代码:
<td><Checkbox
disabled={tpr.disabled} // true or false
checked={tpr.checked} // true or false
onChange={checkboxOnChange} // function handler
targetId={company.id} // number
field={"field1"} />
</td>
复选框定义
const Checkbox = React.memo(({ disabled, checked, onChange, targetId, field }) => {
return (
<input
type="checkbox"
style={ /* omitted */ }
defaultChecked={checked}
disabled={disabled}
onChange={(e) => onChange(e, targetId, field)}
/>
);
});
onChange 处理程序回调
const checkboxOnChange = (e, id, field) => {
const checked = e.target.checked;
console.log("GLOBAL STATE PRE", globalState.companies.list);
let foundCompany = globalState.companies.list.find(company => company[0].id === id);
foundCompany[1][field].checked = checked;
console.log("foundCompany", foundCompany);
console.log("GLOBAL STATE POST", globalState.companies.list);
setGlobalState(prevState => ({
...prevState,
companies: {
...prevState.companies,
list: prevState.companies.list.map(company => {
console.log("company PRE ANYTHING", company);
if (company[0].id === foundCompany[0].id) {
console.log("Inside here");
return foundCompany;
}
console.log("company", company);
return company;
})
}
}));
};
我从 GLOBAL STATE PRE 日志中看到,如果我要为 field1 选中一个框,那么所有公司都会在我修改其他任何内容之前检查 field1。我可以确认,在选中该框之前,globalState 与我期望的一样,在加载时正确设置了所有数据和字段。
在下图中,我选中了第二家公司数组中的 TPR 框,在发生其他任何事情之前,第二家和第三家公司已经将 TPR 设置为 true。
任何帮助将不胜感激,我将分享我能够分享的更多细节。谢谢。
【问题讨论】:
-
因为你在记录它之前就对其进行了变异:
foundCompany[1][field].checked = checked -
该行发生在我执行全局预日志之后,无论如何,由于它来自 find(),它应该只是单个受影响的公司插槽,对吗?我可以理解这条线会影响原始数组,但是更新和记录的顺序没有意义。
-
@jonrsharpe 当我删除整个 foundCompany 位,并将该映射内的 if 语句更改为
if (company[0].id == id) { company[1][field].checked = checked; }时,会发生同样的事情,确认您提到的行无关紧要。 -
“不要改变状态”。在操作状态之前进行浅拷贝或深拷贝。
-
if (company[0].id == id) { company[1][field].checked = checked; }这仍在改变状态。
标签: javascript reactjs react-hooks use-state use-context