【发布时间】:2021-12-11 01:49:41
【问题描述】:
这是我的 App.js,其中包含 Header 和 MainView 一个警报对话框。警报对话框有两个状态控制的道具:
msg={alertMsg} toggleClass={alertToggleClass}
AlertDialog 的任务是显示 className 是否为“alertDlg”,如果为“alertDlg alertDlgClosed”则消失。通过检查器手动测试它(更改类名)表明它工作正常。
因此在初始化的时候alertToggleClass设置为“alertDlg alertDlgClosed”,这样alert对话框默认是隐藏的。
在 MainView 组件内(在 render() 之前)
sendGlobalAlert("Test Alert Msg") 被调用,这只是对 App.js 中 showAlert(msg) 方法的回调。
现在是棘手的部分:在showAlert(msg) 方法中调用setAlertToggleClass("alertDlg"); 会按预期显示自定义警报对话框。但是,尝试通过在 setTimeout 内调用 setAlertToggleClass("alertDlg alertDlgClosed"); 来禁用它会创建到 showAlert(msg)-method 的无限循环。
据我所知,setTimeout(...) 中没有递归。
我无法解释这种行为,希望能提供任何有用的提示。
import './App.css';
import AlertDialog from './components/general/alert-dialog/AlertDialog';
import { Header } from './components/general/Header';
import MainView from './components/main/MainView';
import { useState } from "react";
function App() {
const [alertMsg,setAlertMsg] = useState("");
const [alertToggleClass,setAlertToggleClass] = useState("alertDlg alertDlgClosed");
function showAlert(msg){
console.log("Showing alert dialog");
setAlertMsg(msg); // set message
setAlertToggleClass("alertDlg"); // show alert dialog
setTimeout(function() {
if(alertToggleClass === "alertDlg" ){
setAlertToggleClass("alertDlg alertDlgClosed");
console.log("hide alert");
}
// setAlertToggleClass("alertDlg test");
},3500);
}
return (
<div className="container">
<Header/>
<MainView sendGlobalAlert={showAlert}/>
<AlertDialog msg={alertMsg} toggleClass={alertToggleClass} />
</div>
);
}
export default App;
【问题讨论】:
-
您是否介意制作一个可以显示完整代码的沙盒。如果您愿意,可以使用 codesandbox.io 。这将更容易理解究竟是什么问题。
-
最好将问题中的代码作为minimal reproducible example 而不是外部沙箱。见How do I create a React Stack Snippet with JSX support?。也就是说——
setAlertToggleClass("alertDlg")是异步的并会触发重新渲染,因此您可能希望在此处使用 ref,而不是尝试在setTimeout中读取alertToggleClass。 -
我想我知道问题出在哪里了...被调用立即在 MainView 中,这就是它不断重新渲染的原因。将持续时间从 3500 减少到 100 有助于对它的限制做出反应,导致错误:“重新渲染太多。React 限制渲染数量以防止无限循环。”。将用相应的答案更新问题。
标签: javascript reactjs settimeout