Here is the code:
import React, { useState } from 'react'
function App() {
const [a, setA] = useState(1)
setA(2)
return (
<div>
<h1>{a}</h1>
</div>
);
}
Error. Too many re-renders. React limits the number of renders to prevent an infinite loop.
Why it can cause an infinite loop?
I think the reason is that function ponent just as a render function, so it will cause infinite loop when setState
in render
functions.
Is there any official explanation?
Here is the code:
import React, { useState } from 'react'
function App() {
const [a, setA] = useState(1)
setA(2)
return (
<div>
<h1>{a}</h1>
</div>
);
}
Error. Too many re-renders. React limits the number of renders to prevent an infinite loop.
Why it can cause an infinite loop?
I think the reason is that function ponent just as a render function, so it will cause infinite loop when setState
in render
functions.
Is there any official explanation?
Share Improve this question asked Feb 20, 2020 at 14:36 FaiChouFaiChou 8671 gold badge8 silver badges19 bronze badges 1- if you update state - your ponent re-renders again and setA function called every time when ponent re-rendered. – demkovych Commented Feb 20, 2020 at 14:38
5 Answers
Reset to default 7On each state update React
will re-render the ponent and run all the function body, as the setA(2)
is not enclosed in any hook or function and is a part of the function/ponent body. React
will execute this on each render cycle. This make an infinite loop.
On Component mount React will set the state and go for the ponent update as the state updated, again there is state update React will again re-render the ponent. This cycle will continue until react reaches the re-render limit.
You could avoid this by wrap the state update in hook.
import React, { useState } from 'react'
function App() {
const [a, setA] = useState(1)
useEffect(() => {
setA(2)
},[]);
return (
<div>
<h1>{a}</h1>
</div>
);
}
When calling setA
you actually update a state variable and trigger a re-render of you ponent.
When the ponent re-render it will call setA
(just before the rendering) and will trigger a re-render again.
Can you see the infinite loop ?
Traditionally you update a state variable into a callback (i.e when the user click on a button) or under certains conditions.
In your example, you can directly set a
to 2
function App() {
const [a, setA] = useState(2)
return (
<div>
<h1>{a}</h1>
</div>
);
}
If you want to have the first render with a = 1
, then immediatly have a = 2
, you can use an effect which will be executed only once (because of the empty array for the second argument)
function App() {
const [a, setA] = useState(2)
useEffect(() => setA(2), [])
return (
<div>
<h1>{a}</h1>
</div>
);
}
Because you are setting a new value to the state with setA(2)
, so each time the ponent is rendered the state receives a new value, forcing the ponent to render again
const [rows, setRows] = useState([]);
return {
<Component data= {someData}
selectCallback ={ (rows) => {
console.log(rows);
setRows(rows); // if set State going infinity loop
}}
...remainProps
/>
Its giving infinity loop when trying to setState and if we didn't use the setRows then in console giving right answers means array of objec
Help appreciated.
Because calling setA(2)
causes the ponent to re-render.