import { useEffect, useState } from "react";
function CountSecrets() {
const [secret, setSecret] = useState({ value: "", countSecrets: 0 });
useEffect(() => {
if (secret.value === 'secret') {
setSecret(s => ({...s, countSecrets: s.countSecrets + 1})); }
}, [secret]);
const onChange = ({ target }) => {
setSecret(s => ({ ...s, value: target.value }));
};
return (
<div>
<input type="text" value={secret.value} onChange={onChange} />
<div>Number of secrets: {secret.countSecrets}</div>
</div>
);
}
when the secret is typed the react goes into an infinite loop
I am reading this code through a blog post and its written that the setting the state of an object inside the useEffect creates a new object so the dependency inside the [ ] of useEffect changes and cause infinite loop.
Here is my question when we type and onchange is triggered and is also updating the state, so is updating the state inside the onchange do not creates a new object?And what are the cases of creation of new objects ?
Here is the link of the blog (its the second point) Link
Thumb rule in React is that state object is immutable, can not change it directly. So whenever you want to update state you always create new objects.
Looking at your code, new objects created in both the cases in onChange
as well as in useEffects
. But useEffects
creates infinite loop as dependency gets changed whereas onChange does not create infinite loop as state update does not onChange
again
if you want to avoid an infinite loop, I suggest 2 ways.
[secret] --> [secret.value]
value, countSecrets
as 2 different stateIn summary, when you have object as state then you should always create new object and set it. Where as for value based state, react will take care of it.