简体   繁体   English

多个反应状态更新仅呈现最后一次更新

[英]multiple react state updates renders only the last update

I made a little function to add custom alerts to the state array, and the view renders them.我做了一个小函数来向状态数组添加自定义警报,然后视图呈现它们。 The problem is, if i call the function twice in a row, the first alert is rendered only for a moment, and then its replaced with the second alert.问题是,如果我连续两次调用该函数,第一个警报只会呈现片刻,然后被第二个警报替换。 When i call the method with a mouse click, the function works correctly.当我通过单击鼠标调用该方法时,该函数可以正常工作。

I have tried to apply some waiting before pushing to the array list, but no luck with that.我试图在推送到数组列表之前应用一些等待,但没有运气。

const Element = () => {
  const [alerts, setAlerts] = React.useState([])

  const addAlert = (data) => {
        setAlerts([...alerts, <CustomAlert key={alerts.length} message={data.message} color={data.color} />])
    }

  return (
    <div>
        <button onClick={() => {
                    // this renders only the last state update.
                    addAlert({message: "test", color: "error"}); 
                    addAlert({message: "2", color: "error"})
                }
            }>
           add alert button 
        </button>
      <div>
        {alerts}
      </div>
    </div>
  );
}

React updates the state asynchronously . React 异步更新状态。 This means when you are updating the state 2 times in a row, accessing the value of alerts directly might not have the latest inserted item.这意味着当您连续 2 次更新状态时,直接访问alerts的值可能没有最新插入的项目。 You should use a function instead when calling setAlerts :您应该在调用setAlerts时使用函数:

const [alerts, setAlerts] = React.useState([]);

  const addAlert = (data) => {
    setAlerts((prevAlerts) => {
      const newAlerts = [...prevAlerts];
      newAlerts.push(
        <CustomAlert
          key={alerts.length}
          message={data.message}
          color={data.color}
        />
      );
      return newAlerts;
    });
  };

  return (
    <div>
      <button
        onClick={() => {
          // this renders only the last state update.
          addAlert({ message: "test", color: "error" });
          addAlert({ message: "2", color: "error" });
        }}
      >
        add alert button
      </button>
    </div>
  );

alerts in your code refers to the value of the current render in both case so your addAlert won't work.代码中的alerts在两种情况下都是指当前渲染的值,因此您的 addAlert 将不起作用。 To fix this, you can use the setter version with a function:要解决此问题,您可以使用带有函数的 setter 版本:

setAlerts(currentAlerts => [...currentAlters, <CustomAlert key={alerts.length} message={data.message} color={data.color} />])

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM