Skip to main content
added 172 characters in body
Source Link
Ciro Santilli OurBigBook.com
  • 392.5k
  • 120
  • 1.3k
  • 1.1k

Minimal reproducing example

I was a bit confused as to what exactly triggers the problem, having a minimal immediately runnable example helped me grasp it a little better:

index.html

<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <script src="https://unpkg.com/react@17/umd/react.development.js"></script> <script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script> <script src="https://unpkg.com/@babel/[email protected]/babel.min.js"></script> </head> <body> <div id="root"></div> <script type="text/babel"> function NotMain(props) { props.setN(1) return <div>NotMain</div> } function Main(props) { const [n, setN] = React.useState(0) return <> <NotMain setN={setN} /> <div>Main {n}</div> </> } ReactDOM.render( <Main/>, document.getElementById('root') ); </script> </body> </html> 

fails with error:

react-dom.development.js:61 Warning: Cannot update a component (`Main`) while rendering a different component (`NotMain`). To locate the bad setState() call inside `NotMain`, follow the stack trace as described in https://reactjs.org/link/setstate-in-render

followed by a stack trace:

 at NotMain (<anonymous>:16:9) at Main (<anonymous>:21:31) 

Presumably 16:9 would be the exact line where props.setN(1) is being called from, but the line numbers are a bit messed up because of the Babel JSX translation.

The solution like many other answers said is to do instead:

function NotMain(props) { React.useEffect(() => { props.setN(1) }, []) return <div>NotMain</div> } 

Intuitively, I think that the general idea of why this error happens is that:

You are not supposed to updat state from render methods, otherwise it could lead to different results depending on internal the ordering of how React renders things.

and when using functional components, the way to do that is to use hooks. In our case, useEffect will run after rendering is done, so we are fine doing that from there.

When using classes this becomes slightly more clear and had been asked for example at:

When using functional components however, things are conceptually a bit more mixed, as the component function is both the render, and the code that sets up the callbacks.

Minimal reproducing example

I was a bit confused as to what exactly triggers the problem, having a minimal immediately runnable example helped me grasp it a little better:

index.html

<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <script src="https://unpkg.com/react@17/umd/react.development.js"></script> <script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script> <script src="https://unpkg.com/@babel/[email protected]/babel.min.js"></script> </head> <body> <div id="root"></div> <script type="text/babel"> function NotMain(props) { props.setN(1) return <div>NotMain</div> } function Main(props) { const [n, setN] = React.useState(0) return <> <NotMain setN={setN} /> <div>Main {n}</div> </> } ReactDOM.render( <Main/>, document.getElementById('root') ); </script> </body> </html> 

fails with error:

react-dom.development.js:61 Warning: Cannot update a component (`Main`) while rendering a different component (`NotMain`). To locate the bad setState() call inside `NotMain`, follow the stack trace as described in https://reactjs.org/link/setstate-in-render

followed by a stack trace:

 at NotMain (<anonymous>:16:9) at Main (<anonymous>:21:31) 

Presumably 16:9 would be the exact line where props.setN(1) is being called from, but the line numbers are a bit messed up because of the Babel JSX translation.

The solution like many other answers said is to do instead:

function NotMain(props) { React.useEffect(() => { props.setN(1) }, []) return <div>NotMain</div> } 

Intuitively, I think that the general idea of why this error happens is that:

You are not supposed to updat state from render methods, otherwise it could lead to different results depending on internal the ordering of how React renders things.

and when using functional components, the way to do that is to use hooks. In our case, useEffect will run after rendering is done, so we are fine doing that from there.

When using classes this becomes slightly more clear and had been asked for example at:

Minimal reproducing example

I was a bit confused as to what exactly triggers the problem, having a minimal immediately runnable example helped me grasp it a little better:

index.html

<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <script src="https://unpkg.com/react@17/umd/react.development.js"></script> <script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script> <script src="https://unpkg.com/@babel/[email protected]/babel.min.js"></script> </head> <body> <div id="root"></div> <script type="text/babel"> function NotMain(props) { props.setN(1) return <div>NotMain</div> } function Main(props) { const [n, setN] = React.useState(0) return <> <NotMain setN={setN} /> <div>Main {n}</div> </> } ReactDOM.render( <Main/>, document.getElementById('root') ); </script> </body> </html> 

fails with error:

react-dom.development.js:61 Warning: Cannot update a component (`Main`) while rendering a different component (`NotMain`). To locate the bad setState() call inside `NotMain`, follow the stack trace as described in https://reactjs.org/link/setstate-in-render

followed by a stack trace:

 at NotMain (<anonymous>:16:9) at Main (<anonymous>:21:31) 

Presumably 16:9 would be the exact line where props.setN(1) is being called from, but the line numbers are a bit messed up because of the Babel JSX translation.

The solution like many other answers said is to do instead:

function NotMain(props) { React.useEffect(() => { props.setN(1) }, []) return <div>NotMain</div> } 

Intuitively, I think that the general idea of why this error happens is that:

You are not supposed to updat state from render methods, otherwise it could lead to different results depending on internal the ordering of how React renders things.

and when using functional components, the way to do that is to use hooks. In our case, useEffect will run after rendering is done, so we are fine doing that from there.

When using classes this becomes slightly more clear and had been asked for example at:

When using functional components however, things are conceptually a bit more mixed, as the component function is both the render, and the code that sets up the callbacks.

Source Link
Ciro Santilli OurBigBook.com
  • 392.5k
  • 120
  • 1.3k
  • 1.1k

Minimal reproducing example

I was a bit confused as to what exactly triggers the problem, having a minimal immediately runnable example helped me grasp it a little better:

index.html

<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <script src="https://unpkg.com/react@17/umd/react.development.js"></script> <script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script> <script src="https://unpkg.com/@babel/[email protected]/babel.min.js"></script> </head> <body> <div id="root"></div> <script type="text/babel"> function NotMain(props) { props.setN(1) return <div>NotMain</div> } function Main(props) { const [n, setN] = React.useState(0) return <> <NotMain setN={setN} /> <div>Main {n}</div> </> } ReactDOM.render( <Main/>, document.getElementById('root') ); </script> </body> </html> 

fails with error:

react-dom.development.js:61 Warning: Cannot update a component (`Main`) while rendering a different component (`NotMain`). To locate the bad setState() call inside `NotMain`, follow the stack trace as described in https://reactjs.org/link/setstate-in-render

followed by a stack trace:

 at NotMain (<anonymous>:16:9) at Main (<anonymous>:21:31) 

Presumably 16:9 would be the exact line where props.setN(1) is being called from, but the line numbers are a bit messed up because of the Babel JSX translation.

The solution like many other answers said is to do instead:

function NotMain(props) { React.useEffect(() => { props.setN(1) }, []) return <div>NotMain</div> } 

Intuitively, I think that the general idea of why this error happens is that:

You are not supposed to updat state from render methods, otherwise it could lead to different results depending on internal the ordering of how React renders things.

and when using functional components, the way to do that is to use hooks. In our case, useEffect will run after rendering is done, so we are fine doing that from there.

When using classes this becomes slightly more clear and had been asked for example at: