为什么地图中的 setState 挂钩只设置最后一个对象?
why setState hook in the map set last object only?
我在 react-admin 中有 2 个组件,子组件设置父组件的状态。
子组件有useEffect触发父组件下面的方法
const [approved, setAproved] = useState([]);
useEffect(() => {
console.log(JSON.stringify(approved))
}, [approved])
const setapprovedamount = (id, approvedAmount) => {
if(approved.length!==0)
{
// if the child run 3 times
// this line runs 3 times
console.log("set Aproved with" +id+ " and amount : "+approvedAmount)
// but this line update only the last object
setAproved(
approved.map(item =>
(item.id == id)
? {...item, totalApproved : approvedAmount}
: item
)
)
}
else
{
setAproved(approved =>[...approved, {
id: id,
totalApproved: approvedAmount
}] )
}
}
useEffect(() => {
console.log(JSON.stringify(approved))
}, [approved])
So **for example** if I have 3 times load, the Console is:
file.js:168 set Aproved with44 and amount : 799.71
file.js:168 set Aproved with45 and amount : 845.98
file.js:168 set Aproved with46 and amount : 890.83
file.js:96
[{"id":44,"totalApproved":null},{"id":45,"totalApproved":null},{"id":46,"totalApproved":890.83}]
所以该方法在触发时运行了 3 次,但是,它只设置了父组件状态数组中呈现的最后一个值
因为 State and Lifecycle 的工作方式。
如果您想通过setState
触发多个链接状态更新,您需要让组件在每次状态更新时完成其循环 - 要事第一。
因此,基本的解决方案是隐含使用chainedsetTimeout
调用来委托每次状态更新,让每个函数调用完成一个组件,完整的生命周期。
setTimeout(function() {
setState(firstState)
setTimeout(function() {
setState(secondState)
});
});
我在 react-admin 中有 2 个组件,子组件设置父组件的状态。
子组件有useEffect触发父组件下面的方法
const [approved, setAproved] = useState([]);
useEffect(() => {
console.log(JSON.stringify(approved))
}, [approved])
const setapprovedamount = (id, approvedAmount) => {
if(approved.length!==0)
{
// if the child run 3 times
// this line runs 3 times
console.log("set Aproved with" +id+ " and amount : "+approvedAmount)
// but this line update only the last object
setAproved(
approved.map(item =>
(item.id == id)
? {...item, totalApproved : approvedAmount}
: item
)
)
}
else
{
setAproved(approved =>[...approved, {
id: id,
totalApproved: approvedAmount
}] )
}
}
useEffect(() => {
console.log(JSON.stringify(approved))
}, [approved])
So **for example** if I have 3 times load, the Console is:
file.js:168 set Aproved with44 and amount : 799.71
file.js:168 set Aproved with45 and amount : 845.98
file.js:168 set Aproved with46 and amount : 890.83
file.js:96
[{"id":44,"totalApproved":null},{"id":45,"totalApproved":null},{"id":46,"totalApproved":890.83}]
所以该方法在触发时运行了 3 次,但是,它只设置了父组件状态数组中呈现的最后一个值
因为 State and Lifecycle 的工作方式。
如果您想通过setState
触发多个链接状态更新,您需要让组件在每次状态更新时完成其循环 - 要事第一。
因此,基本的解决方案是隐含使用chainedsetTimeout
调用来委托每次状态更新,让每个函数调用完成一个组件,完整的生命周期。
setTimeout(function() {
setState(firstState)
setTimeout(function() {
setState(secondState)
});
});