我有一系列警报作为我的状态。
我正试图允许我的用户通过单击警报来手动关闭警报,并在几秒钟后自动将其关闭。
当前,只有第三个警报会自动清除,其余的则保持不变。
使用当前的实现,我还能实现我的目标吗? 如果不是,什么是正确的探索方向?
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);
谢谢。
答案 0 :(得分:0)
检查代码的修改示例,我认为它或多或少可以达到您的预期目的,但是可能会出现故障。我感觉效果不佳,正在关闭setTimeout警报。似乎setTimeout正在删除可能已经删除的东西。因此,为了保持并发状态,我正在维护一个队列,该队列将保留要删除的项目。我还使用了id
而不是依赖可以在拼接后更改的索引。让我知道您是否需要进一步的帮助。
根据您需要在setTimeouts
上进行锻炼的方式,为什么会在渲染它们后将它们全部排在瞬间之间,这会给人以为它们都是一起删除
import React, { useState, useEffect } from "react";
import ReactDOM from "react-dom";
import "./styles.css";
function App() {
useEffect(() => {
setInterval(addAlert, 5000);
setInterval(dismissAlert, 6000);
}, []);
const addAlert = () => {
setAlerts([
...alerts,
{ id: new Date().getTime(), message: "new alert" + Math.random() }
]);
};
const [alerts, setAlerts] = useState([
{ id: 1, message: "Alert 1" },
{ id: 2, message: "Alert 2" },
{ id: 3, message: "Alert 3" },
{ id: 4, message: "Alert 4" }
]);
const [alertsToRemove, addAlertsToRemove] = useState([]);
const queueRemoval = alertId => {
if (alertsToRemove.indexOf(alertId) <= -1) {
alertsToRemove.push(alertId);
addAlertsToRemove(alertsToRemove);
}
};
const dismissAlert = () => {
alertsToRemove.forEach(id => {
var alertToDelete = alerts.find(a => a.id == id);
alerts.splice(alerts.indexOf(alertToDelete));
setAlerts(alerts);
});
addAlertsToRemove([]);
};
return (
<div className="App">
<Alerts alerts={alerts} queueRemoval={queueRemoval} />
</div>
);
}
const Alerts = ({ alerts, queueRemoval }) => (
<div className="alerts">
{alerts.map((alert, i) => (
<Alert
key={i}
alert={alert}
queueRemoval={() => queueRemoval(alert.id)}
/>
))}
</div>
);
const Alert = ({ alert, queueRemoval }) => {
useEffect(() => {
const timerId = setTimeout(queueRemoval, 3000);
return () => {
console.log("clearing timeout");
clearTimeout(timerId);
};
}, []);
return (
<div className="alert" onClick={queueRemoval}>
<p>{alert.message}</p>
</div>
);
};
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);