Lets say I have some state that is dependent on some other state (eg when A changes I want B to change).
Is it appropriate to create a hook that observes A and sets B inside the useEffect hook?
Will the effects cascade such that, when I click the button, the first effect will fire, causing b to change, causing the second effect to fire, before the next render? Are there any performance downsides to structuring code like this?
let MyComponent = props => {
let [a, setA] = useState(1)
let [b, setB] = useState(2)
useEffect(
() => {
if (/*some stuff is true*/) {
setB(3)
}
},
[a],
)
useEffect(
() => {
// do some stuff
},
[b],
)
return (
<button
onClick={() => {
setA(5)
}}
>
click me
</button>
)
}
Best Answer
Generally speaking, using
setState
insideuseEffect
will create an infinite loop that most likely you don't want to cause. There are a couple of exceptions to that rule which I will get into later.useEffect
is called after each render and whensetState
is used inside of it, it will cause the component to re-render which will calluseEffect
and so on and so on.One of the popular cases that using
useState
inside ofuseEffect
will not cause an infinite loop is when you pass an empty array as a second argument touseEffect
likeuseEffect(() => {....}, [])
which means that the effect function should be called once: after the first mount/render only. This is used widely when you're doing data fetching in a component and you want to save the request data in the component's state.