为什么setState钩子仅在地图上设置最后一个对象?

时间:2020-10-26 01:45:31

标签: hook setstate react-admin

在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次,但是它仅设置了在父组件的状态数组中呈现的最后一个值

1 个答案:

答案 0 :(得分:0)

由于State and Lifecycle的工作原理。

如果您想通过setState触发多个链式状态更新,则需要让组件在每次状态更新时都完成其循环-首先要做的事情。

因此,基本解决方案是暗示使用chained setTimeout调用来委派每个状态更新,让每个函数调用完成一个组件,整个生命周期。

setTimeout(function() {
    setState(firstState)
    setTimeout(function() {
        setState(secondState)
    });
});