Reputation: 837
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 component just as a render function, so it will cause infinite loop when setState
in render
functions.
Is there any official explanation?
Upvotes: 5
Views: 5184
Reputation: 577
Because calling setA(2)
causes the component to re-render.
Upvotes: 0
Reputation: 1189
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.
Upvotes: 0
Reputation: 10569
On each state update React
will re-render the component 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/component 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 component update as the state updated, again there is state update React will again re-render the component. 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>
);
}
Upvotes: 5
Reputation: 18083
When calling setA
you actually update a state variable and trigger a re-render of you component.
When the component 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>
);
}
Upvotes: 3
Reputation: 659
Because you are setting a new value to the state with setA(2)
, so each time the component is rendered the state receives a new value, forcing the component to render again
Upvotes: 0