Here is my App.js that contains beside Header and the MainView an AlertDialog. Alert dialog has two state controlled props:
msg={alertMsg} toggleClass={alertToggleClass}
The task of AlertDialog is to show if the className is "alertDlg" and disappear if it's "alertDlg alertDlgClosed". Testing it via the inspector manually (changing className) shows, that it works fine.
Therefore alertToggleClass is set to "alertDlg alertDlgClosed" when initializing, so that the alert dialog is hided by default.
Within the MainView Component (before render())
sendGlobalAlert("Test Alert Msg")
gets called which is simply a callback to the showAlert(msg)
method in App.js.
Now here goes the tricky part: calling setAlertToggleClass("alertDlg");
in showAlert(msg)
-method shows the custom alert dialog as expected. However trying to disable it by calling setAlertToggleClass("alertDlg alertDlgClosed");
within the setTimeout creates an infinite loop to showAlert(msg)
-method.
As far as I can see, there is no recursivity is in setTimeout(...)
.
I can't explain this behavior and would appreciate any helpful hints.
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;
The sendGlobalAlert("Test Alert Msg");
within the MainView was the issue here.
After this call, which is basically a callback to App.js's showAlert(msg)
method, the props stored in state, that is used by AlertDialog, were changed. Due to an update to these props, AlertDialog rerendered and that again caused a rerender in App.js, which means that it elements had to rerender too. As it was including MainView, the rerender of App.js meant a rerender of MainView, which calls the sendGlobalAlert("Test Alert Msg");
and started the recursiveness.
This is how the MainView looks like:
const MainView = ({sendGlobalAlert}) => {
sendGlobalAlert("Test Alert Msg");
return (
<div className="main-view" >
<BillView/>
<InteractionView sendGlobalAlert={sendGlobalAlert}/>
</div>
)
}