我在我的一个反应组件中设置多个状态时遇到问题。我的最终目标是:首先要设置“ casesData”状态(见下文),以便在每个后续单击事件中将“ selected”的值设置为“ true”或“ false”。然后,我想通过“ casesData”进行映射以找到“ selected:true”的位置,然后将“ case”的值添加到“ chosenCases”。因此,最后,“ chosenCases”可能看起来像:['case1','case2'],只要它们在'casesData'中的相应对象等于'selected:true'。
我的初始状态是这样设置的:
const [chosenCases, setChosenCases] = useState([]);
const [casesData, setCasesData] = useState([
{
case: 'Case1',
description: 'some description',
selected: false,
},
{
case: 'Case2',
description: 'some description',
selected: false,
},
]);
我通过“ casesData”状态映射将内容呈现到屏幕上。然后,我从onClick调用一个函数以开始更新状态:
return (
<>
{casesData.map(
(
casex // casex because 'case' is a reserved word
) => {
return (
<span
onClick={selectCase}
data-case={casex.case}
>
<p>{casex.case}</p>
<p>{casex.description}</p>
</span>
);
}
)}
</>
);
这是应该更新我两个状态的函数。
const selectCase = (event) => {
console.log(event.target.getAttribute('data-case')); // e.g. 'case2'
setCasesData(
[...casesData].map((object) => {
if (
object.case.toLowerCase() ===
event.target.getAttribute('data-case').toLowerCase()
) {
return {
...object,
selected: !object.selected,
};
} else return object;
})
);
let newArray = [];
casesData.map((object) => {
if (object.selected === true) {
newArray.push(object.case.toLowerCase());
}
});
setChosenCases(newArray);
};
如果运行上述功能后将状态记录到控制台,我会看到'casesData'得到正确更新,但是'chosenCases'总是落后一步。例如,“ chosenCases”在函数的第一次运行时保持为空,但在第二次运行时被设置(例如['case2'],但数据将反映先前的函数调用)。
任何帮助将不胜感激。我想知道最合适的设置方法。
答案 0 :(得分:0)
最简单的方法是将新的casesData
存储在变量中,这样您就不必等待新的渲染即可看到新状态:
const selectCase = (event) => {
console.log(event.target.getAttribute('data-case')); // e.g. 'case2'
const newCasesData = casesData.map((object) =>
(object.case.toLowerCase() === event.target.getAttribute('data-case').toLowerCase())
? {
...object,
selected: !object.selected,
}
: object
)
setCasesData(newCasesData);
setChosenCases(
newCasesData
.filter(obj => obj.selected)
.map(obj => obj.case.toLowerCase())
);
};
您可能还想重新考虑是否需要诸如chosenCases
之类的派生状态,并且只需要在渲染时弄清楚选定的情况即可。这将使您的代码更易于推理,因为您不必担心两个状态的配置。