Reactjs 使用 setTimeout 创建无限循环
Reactjs creates infinite loop using setTimeout
这是我的 App.js,其中包含 Header 和 MainView
一个警报对话框。警报对话框有两个状态控制的道具:
msg={alertMsg} toggleClass={alertToggleClass}
AlertDialog 的任务是显示类名是否为“alertDlg”,如果是“alertDlg alertDlgClosed”则消失。通过检查器手动测试(更改类名)表明它工作正常。
因此alertToggleClass在初始化时设置为“alertDlg alertDlgClosed”,默认情况下隐藏警告对话框。
在 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;
MainView 中的 sendGlobalAlert("Test Alert Msg");
是这里的问题。
在这个调用之后,基本上是对 App.js 的 showAlert(msg)
方法的回调,AlertDialog 使用的存储在状态中的道具被改变了。由于对这些道具的更新,AlertDialog 重新呈现并再次导致 App.js 中的重新呈现,这意味着它的元素也必须重新呈现。由于它包括 MainView,App.js 的重新渲染意味着 MainView 的重新渲染,它调用 sendGlobalAlert("Test Alert Msg");
并开始递归。
主视图是这样的:
const MainView = ({sendGlobalAlert}) => {
sendGlobalAlert("Test Alert Msg");
return (
<div className="main-view" >
<BillView/>
<InteractionView sendGlobalAlert={sendGlobalAlert}/>
</div>
)
}
这是我的 App.js,其中包含 Header 和 MainView 一个警报对话框。警报对话框有两个状态控制的道具:
msg={alertMsg} toggleClass={alertToggleClass}
AlertDialog 的任务是显示类名是否为“alertDlg”,如果是“alertDlg alertDlgClosed”则消失。通过检查器手动测试(更改类名)表明它工作正常。
因此alertToggleClass在初始化时设置为“alertDlg alertDlgClosed”,默认情况下隐藏警告对话框。
在 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;
MainView 中的 sendGlobalAlert("Test Alert Msg");
是这里的问题。
在这个调用之后,基本上是对 App.js 的 showAlert(msg)
方法的回调,AlertDialog 使用的存储在状态中的道具被改变了。由于对这些道具的更新,AlertDialog 重新呈现并再次导致 App.js 中的重新呈现,这意味着它的元素也必须重新呈现。由于它包括 MainView,App.js 的重新渲染意味着 MainView 的重新渲染,它调用 sendGlobalAlert("Test Alert Msg");
并开始递归。
主视图是这样的:
const MainView = ({sendGlobalAlert}) => {
sendGlobalAlert("Test Alert Msg");
return (
<div className="main-view" >
<BillView/>
<InteractionView sendGlobalAlert={sendGlobalAlert}/>
</div>
)
}