我正在尝试更改数组中的值并使用useEffect重新呈现组件,但useEffect不会触发。值已更改,但调用useState无效。
const handleOptionClick = (e) => {
var el = document.getElementById(e.currentTarget.id);
var tar = el.getAttribute("data");
var ans = awnsers;
ans.map((res) => {
if (res.Awnser === tar) {
res.IsChecked = !res.IsChecked;
return true;
}
return true;
});
setAwnsers(ans);
}
和
useEffect(() => {
console.log(awnsers);
},[awnsers])
答案 0 :(得分:0)
React在更新状态时执行Object.is比较,如果先前状态和当前状态的引用相同,则检查失败并且不触发重新渲染
地图还返回了数组的新引用,您不得更改原始数组,而应以不可变的方式对其进行更新
const handleOptionClick = (e) => {
var el = document.getElementById(e.currentTarget.id);
var tar = el.getAttribute("data");
var ans = awnsers; // Check for typo
ans = ans.map((res) => {
if (res.Awnser === tar) {
{...res, IsChecked:!res.IsChecked};
}
return res;
});
setAwnsers(ans);
}
P.S。您还可以使用功能性的setState方法来更新状态,因为您是根据先前的值更新当前状态的
const handleOptionClick = (e) => {
var el = document.getElementById(e.currentTarget.id);
var tar = el.getAttribute("data");
setAwnsers(prevAns => ans.map((res) => {
if (res.Awnser === tar) {
{...res, IsChecked:!res.IsChecked};
}
return res;
}));
}
答案 1 :(得分:0)
您不会保存保存在状态中的array :: map函数的结果,因此awnsers
数组中的状态引用值基本上不会改变,并且组件也不会重新呈现
const handleOptionClick = (e) => {
var el = document.getElementById(e.currentTarget.id);
var tar = el.getAttribute("data");
setAwnsers(prevAwnser => prevAwnser.map(res => ({
...res,
IsChecked: res.Awnser === tar ? !res.IsChecked : res.IsChecked,
})));
}
答案 2 :(得分:-1)
由于您正在map
上进行ans
,因此我将其视为一个数组。数组通过引用复制。因此,要做出反应以重新渲染awnsers
,您将必须创建一个新数组。
var ans = [...awnsers]; // or JSON.parse(JSON.stringify(awnsers)) for deep clone
ans.map((res) => {
if (res.Awnser === tar) {
res.IsChecked = !res.IsChecked;
return true;
}
return true;
});
setAwnsers(ans);
Awnsers
也是错字吗?您是说Answers
吗?