多个反应状态更新仅呈现最近的更新

时间:2020-09-30 10:12:47

标签: javascript reactjs react-hooks state

我做了一个小功能,将自定义警报添加到状态数组,然后视图将其呈现。问题是,如果我连续两次调用该函数,则第一个警报仅显示一会儿,然后将其替换为第二个警报。当我用鼠标单击调用该方法时,该功能将正常工作。

我试图在推送到数组列表之前进行一些等待,但是没有运气。

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>
  );
}

2 个答案:

答案 0 :(得分:1)

React更新状态asynchronously。这意味着当您连续两次更新状态时,直接访问alerts的值可能没有最新插入的项目。调用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>
  );

答案 1 :(得分:0)

在两种情况下,代码中的

alerts都引用当前渲染的值,因此您的addAlert无法正常工作。要解决此问题,可以使用带有功能的setter版本:

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