【问题标题】:Show alert after few second in react反应几秒钟后显示警报
【发布时间】:2021-04-26 09:43:25
【问题描述】:

我正在尝试创建一个应用程序,它会在我单击任何项​​目时显示警报,并且此警报会在几秒钟后消失。

我创建了一个非常小的应用程序来测试这一点,我正在向状态添加一个元素并显示它。

<!DOCTYPE html>
<html>

<head>
  <title>React 17 </title>
</head>

<body>
  <div id="app"></div>
  <script src="https://unpkg.com/@babel/standalone@7.13.15/babel.min.js"></script>

  <!-- babel is required in order to parse JSX -->
  <script src="https://unpkg.com/react@17/umd/react.production.min.js"></script>
  <script src="https://unpkg.com/react-dom@17/umd/react-dom.production.min.js"></script>
  <script crossorigin="anonymous" type="text/babel">


    class Test extends React.Component {

      constructor(props) {
        super(props);

        this.state = {
          showAlert: []
        }
      }

      showAlert = (e) => {
        //alert(e.target.value);

        const old = this.state.showAlert;



        this.setState((prevState) => {
          let arr = prevState.showAlert;
          arr.push(e.target.value);
          return { showAlert: arr }
        });

        setTimeout(
          function () {
            this.setState((prevState) => {
              const array = prevState.showAlert.filter(element => element !== e.target.value);
              return { showAlert: array }
            });
          }
            .bind(this),
          2000
        );

      }

      render() {
        return (
          <div>

            {
              this.state.showAlert.length > 0 &&

              <ul>
                {this.state.showAlert.map((value, index) => {
                  return <li key={index}>{value}</li>
                })}
              </ul>
            }

            <select onChange={this.showAlert} multiple>
              <option value="Test 1">Test 1</option>
              <option value="Test 2">Test 2</option>
              <option value="Test 3">Test 3</option>
              <option value="Test 4">Test 4</option>
              <option value="Test 5">Test 5</option>
              <option value="Test 6">Test 6</option>
            </select>

          </div>
        )
      }
    }

    ReactDOM.render(<Test />, document.getElementById("app"));
  </script>
</body>

</html>

我面临的问题是,如果我在两秒钟之前单击另一个项目,只有单击一次,警报通知才会消失,只有最后一个项目会消失而不是第一个项目。 https://www.loom.com/share/0287300eaef147aeaa5d11e9dd108d7e

【问题讨论】:

  • 您使用index 作为键,但更改了警报数组的顺序,因此 React 无法为每个警报存储一致的状态。相反,您应该使用唯一标识符作为每个警报的键。
  • @pilchard - 很抱歉,您能否更改代码。

标签: javascript reactjs react-native rxjs


【解决方案1】:

这是一个使用功能组件的示例。警报数组在父级中保持状态,而各个Alert 组件将自己的计时器设置在useEffect 中并进行适当清理。每个警报都有一个唯一的id 用作键。

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

  const showAlert = (e) => {
    const newAlert = {
      id: `${e.target.value}_${performance.now()}`,
      value: e.target.value
    };
    setAlerts(prev => [...prev, newAlert]);
  };

  const clearAlert = (_id) => {
    setAlerts(prev => prev.filter(({ id }) => id !== _id));
  };

  return (
    <div className="App">
      <select onChange={showAlert}>
        <option value="Test 1">Test 1</option>
        <option value="Test 2">Test 2</option>
        <option value="Test 3">Test 3</option>
        <option value="Test 4">Test 4</option>
        <option value="Test 5">Test 5</option>
        <option value="Test 6">Test 6</option>
      </select>
      {!!alerts.length &&
        <ul>
          {alerts.map(alert =>
            <li key={alert.id}>
              <Alert alert={alert} clearAlert={clearAlert} />
            </li>
          )}
        </ul>
      }
    </div>
  )
}

const Alert = ({ alert, clearAlert }) => {

  React.useEffect(() => {
    const visible = setTimeout(() => clearAlert(alert.id), 3000);
    return () => clearTimeout(visible);
  }, []);

  return (
    <p>{alert.value}</p>
  );
}


ReactDOM.render(
  <App />,
  document.getElementById("root")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>

<div id="root"></div>

【讨论】:

  • 谢谢@pilchard,但我仍在学习,似乎整个代码都已更改。我可以在我的代码中做些什么来达到预期的结果。
猜你喜欢
  • 1970-01-01
  • 2019-01-02
  • 2011-12-30
  • 2021-09-08
  • 2016-06-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多