Why you should avoid using the effect>setState pattern in React
... and what to replace it with

Let's say you have an initialItems array that you fetch from an API and set it in state like this:
const [items, setItems] = useState<T[]>(initialItems)
You may instinctively realize, initialItems is only set as the default value of this state, so items won't update when initialItems changes, and you'd be right. If the initialItems passed to your component or hook is fetched from an API and later changes, items won't reflect it.
To resolve this issue, you may reach for an effect, so that the items state is updated when the fetched data changes:
useEffect(() => {
setItems(initialItems)
}, [initialItems])
Stop right there! There's a much simpler way to do this that doesn't require an effect and is recommended by the React team.
Why you shouldn't use an effect here
React has published a doc titled You Might Not Need an Effect. In summary, it explains that effects aren't necessary in most cases and are used frequently in use cases where the code would perform better without one. You may read the article for yourself, but I want to highlight the Adjusting some state when a prop changes section. It states:
Every time the
itemschange, theListand its child components will render with a staleselectionvalue at first. Then React will update the DOM and run the Effects. Finally, thesetSelection(null)call will cause another re-render of theListand its child components, restarting this whole process again.
Essentially, calling an effect to update a list in state causes more unnecessary re-renders, which we should always try to avoid when working with React.
The simple fix
In our case, and as shown by the article, we can replace the effect that calls setItems with the following. Place this after your useState call in your code:
if (initialItems !== items) {
// Update the state variable when `initialItems` changes
setItems(initialItems)
}
So on every render of your component or hook, this conditional simply checks if the prop has changed from the initial value the state variable was given, and updates state in that case. No useEffect necessary and no unnecessary re-renders.
Conclusion
I thought this post would be a useful, quick read for any other developers that find themselves often reaching for the useEffect -> setSomeState() crutch, as I have. That entire article from the React team is really useful to understand when and when not to use effects and I recommend reading it.



