I am building a react component as a functional component.
I am gonna narrow it down here to a minimal problem, you can imagine it as a DataGrid containing data that is fetched from an external API which is saved to that state so that it can be used for the DataGrid.
[orders, setOrders] = React.useState(getSomeIntialValuesToShowWhileFetching())
Then I have the useEffect hook to run only on mounting to fetch the data.
useEffect(() => {
let res = await getDataFromApi();
setOrders(res);
}, [])
So far so good. Now I have another calculation, that needs to be done after orders was filled with the data, think of it as a total of all orders.
How do I achieve this, due to the async nature of setOrders(res)
?
I tried using another useEffect, that has orders in its dependency array. The problem here is that this also runs on the inital mounting of the component.
As setOrders is asynchronously but does not return a Promise, I don´t see a way to await it or chain it with then operations.
I am grateful for answers as I am still learning how to deal with hooks.
2
Answers
You can use another UseEffect that has orders in its dependency array, but with a conditional that checks if orders received any value. Example:
You might consider using a custom hook known as
useDidUpdateEffect
. In essence, it is a normaluseEffect
but slightly modified to skip the initial render.It uses the
didMountRef
as a flag, which is false on init. Hence your function will run only ifdidMountRef.current == true
which happens after the initial render.That way your calculation will only run when your dependency(
orders
) actually updates.Hook definition
Usage