【发布时间】:2019-02-19 10:21:33
【问题描述】:
我有一组警报作为我的状态。
我正在尝试让我的用户通过单击手动关闭警报,并在几秒钟后自动关闭它。
目前只有第三个警报会自动清除,其余的保持不变。
我什至可以通过当前的实现来实现我的目标吗? 如果不是,那么正确的探索方向是什么?
import React, { useState, useEffect } from "react";
import ReactDOM from "react-dom";
import "./styles.css";
function App() {
const [alerts, setAlerts] = useState([
{ message: "Alert 1" },
{ message: "Alert 2" },
{ message: "Alert 3" },
{ message: "Alert 4" }
]);
const dismissAlert = alertIndex => {
setAlerts([
...alerts.slice(0, alertIndex),
...alerts.slice(alertIndex + 1)
]);
};
return (
<div className="App">
<Alerts alerts={alerts} dismissAlert={dismissAlert} />
</div>
);
}
const Alerts = ({ alerts, dismissAlert }) => (
<div className="alerts">
{alerts.map((alert, i) => (
<Alert key={i} alert={alert} dismissAlert={() => dismissAlert(i)} />
))}
</div>
);
const Alert = ({ alert, dismissAlert }) => {
useEffect(() => {
const timerId = setTimeout(dismissAlert, 1000);
return () => {
console.log("clearing timeout");
clearTimeout(timerId);
};
}, []);
return (
<div className="alert" onClick={dismissAlert}>
<p>{alert.message}</p>
</div>
);
};
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
提前致谢。
【问题讨论】:
-
您可能需要另一种方法来识别需要解除的警报,因为索引可能会在请求解除和解除实际发生的时间之间发生变化。
-
显然 React 在更新
alerts时没有清除我的setTimeout,因为它得到了相同的key(我想这就是为什么eslint总是抱怨索引作为键)更改 @ 987654327@ 到i + alert.message解决了我的问题。 -
我认为它还有另一个错误。 4 条消息应同时清除。但它清楚的顺序
-
是的,因为
Alert会重新渲染并在安装时获得一个新的setTimeout,我现在正尝试使用React.memo解决这个问题。
标签: javascript reactjs