Uncaught Invariant Violation: Too many re-renders. React limits the number of renders to prevent an infinite loop Uncaught Invariant Violation: Too many re-renders. React limits the number of renders to prevent an infinite loop javascript javascript

Uncaught Invariant Violation: Too many re-renders. React limits the number of renders to prevent an infinite loop


I suspect that the problem lies in the fact that you are calling your state setter immediately inside the function component body, which forces React to re-invoke your function again, with the same props, which ends up calling the state setter again, which triggers React to call your function again.... and so on.

const SingInContainer = ({ message, variant}) => {    const [open, setSnackBarState] = useState(false);    const handleClose = (reason) => {        if (reason === 'clickaway') {          return;        }        setSnackBarState(false)      };    if (variant) {        setSnackBarState(true); // HERE BE DRAGONS    }    return (        <div>        <SnackBar            open={open}            handleClose={handleClose}            variant={variant}            message={message}            />        <SignInForm/>        </div>    )}

Instead, I recommend you just conditionally set the default value for the state property using a ternary, so you end up with:

const SingInContainer = ({ message, variant}) => {    const [open, setSnackBarState] = useState(variant ? true : false);                                   // or useState(!!variant);                                   // or useState(Boolean(variant));    const handleClose = (reason) => {        if (reason === 'clickaway') {          return;        }        setSnackBarState(false)      };    return (        <div>        <SnackBar            open={open}            handleClose={handleClose}            variant={variant}            message={message}            />        <SignInForm/>        </div>    )}

Comprehensive Demo

See this CodeSandbox.io demo for a comprehensive demo of it working, plus the broken component you had, and you can toggle between the two.


In SnackbarContentWrapper you need to change

<IconButton  key="close"  aria-label="Close"  color="inherit"  className={classes.close}  onClick={onClose} // change this>

to

<IconButton  key="close"  aria-label="Close"  color="inherit"  className={classes.close}  onClick={() => onClose()} // to this>

So that it only fires the action when you click.

Alternatively, you could just curry the handleClose in SignInContainer to

const handleClose = () => (reason) => {  if (reason === 'clickaway') {    return;  }  setSnackBarState(false)};

It's the same.


You must link an event in your onClick. Additionally, the click function must receive the event. See the example

export default function Component(props) {    function clickEvent (event, variable){        console.log(variable);    }    return (        <div>            <IconButton                key="close"                aria-label="Close"                color="inherit"                onClick={e => clickEvent(e, 10)}            >        </div>    )}