为什么地图中的 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)
    });
});