I am starting to learn Redux and the thunk library.
I have an Actions.js which holds the function:
export const fetchInventory = (user_id) => {
return (dispatch) => {
dispatch(fetchInventoryData());
fetch("url", {
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
//make sure to serialize your JSON body
body: JSON.stringify({ user_id }),
})
.then((res) => res.json())
.then((res) => {
saveInventory(res);
dispatch(fetchInventorySuccess(res));
})
.catch((err) => dispatch(fetchInventoryFailure(err)));
};
};
and a Container.js with the useEffect as follows:
useEffect(() => {
if (inventory.inventoryData.length > 0) return;
else if (user_id) fetchInventory(user_id);
else return [];
}, [user_id]);
EsLint gives me a warning that I am missing fetchInventory and inventory in the dependency array. However, since inventory is the state that this fetch will update, including it throws us into an infinite fetch. Also, the user_id necessary here is something that comes from a fetch request prior to this one. In a situation like this, what would go into the dependency array and why?
inventory
should certainly be included in the dependency array since it is referenced in the hook callback (and likely also the fetchInventory
action creator, for the same reason).
I believe the issue here is an improper guard clause (i.e. condition) for which you are calling the callback that updates state (and dependency).
The if-else-if-else
is the issue. when the first condition fails, because inventory.inventoryData.length
is non-zero, the second condition is checked, and sure enough there's a defined user_id
value and the callback is invoked.
From what I can gather, the condition you want is "if there is no inventory data AND there is a user id, then fetch inventory, otherwise do nothing".
Try simplifying your condition and branching factor.
useEffect(() => {
if (!inventory.inventoryData.length && user_id) {
fetchInventory(user_id)
}
}, [fetchInventory, inventory.inventoryData, user_id]);