A component in my NextJS 13 project has two useEffect hooks, one that sets a React Context state array variable called singleRecipe, and another that I would like to set another local state variable called ingredientsArr. The issue arises on first render, I am receiving undefined for the singleRecipe state variable when my code reaches the second useEffect. How would I go about updating the ingredientsArr variable to an element from the singleRecipe only once singleRecipe is defined?
useEffect(() => {
setSingleRecipe(recipes.find(({id}) => id === Number(recipeID)))
})
useEffect(() => {
setIngredientsArr(JSON.parse(singleRecipe.ingredients))
}, [singleRecipe])
- singleRecipe is stored in context state and ingredientsArr is local to this component
3
Answers
You can check if the value is
undefined
before trying to use it. For example:Or perhaps use optional chaining and conditionally set to a blank array if the overall value is "falsy":
Alternatively, if the goal is to perform both of these operations in one overall effect then just use one call to
useEffect
:It’s worth noting, if only for future readers… This effect will run on every render. Which is probably not what you want. Especially if the effect updates state, which triggers another render.
You can modify this effect to only run on the first render by providing an empty dependency array:
Or to run only when
recipeID
changes:I think you can achieve this by adding a check to the second use effect:
Although it seems strange that the first
useEffect
has no dependencies. What isrecipeId
? If that is a prop/state var you should probably include it in the dep array:If you don’t include it in the dep array, it will set it on every render which isn’t ideal.
The reason it’s undefined is you are setting it in the first
useEffect
and state updates asynchronously (so the new value isn’t available until the next render).you don’t really need two useEffect here:
Note that in your code the first
useEffect
will run on each component render because it does not have a dependency array.