1

I am new to react and just learned how to use useEffect and useState/useReducer. Now I am facing a problem. Assume I have a useEffect like below and states A,B,C,D:

React.useEffect(() => {
   D = fetchReq(A, B, C);
}, [A, B, C])

React.useEffect(() => {
   B = fetchReq(A)
}, [A])

React.useEffect(() => {
   C = fetchReq(B)
}, [B])

The problem is B also depends on A, so everytime A gets update, B needs to update by an async req accordingly i.e B = fetchReq(A). And C depends on B, C = fetchReq(B). So once if A change, it may trigger incorrect behavior like fetchReq(A,B_old,C_old) or fetchReq(A,B,C_old), which is unwanted.

How should I fix this problem?

jackie_G
  • 13
  • 2
  • Do some validations before running the function, you can get previous values, check this post: https://reactjs.org/docs/hooks-faq.html#how-to-get-the-previous-props-or-state – SimonDX Mar 08 '22 at 15:18

3 Answers3

1

I don't know why you would want to chain it like this as this is causing multiple re-renders for no real gain. You do not mention that B,C,D are being managed using useState. If this is purely a chain of requests that need to be performed on A updating, I would do something like this:

useEffect(() => {
    async (() => {
        const B = await fetchReq(A);
        const C = await fetchReq(B);
        const D = await fetchReq(A, B, C);
    })();
}, [A])
  • useEffect should be aware of all the values involved – SimonDX Mar 08 '22 at 15:19
  • Please elaborate on this – Nicholas Barfknecht Mar 09 '22 at 08:08
  • I think Simon means is that according to [link](https://reactjs.org/docs/hooks-reference.html#useeffect). **If you use this optimization, make sure the array includes all values from the component scope (such as props and state) that change over time and that are used by the effect.** – jackie_G Mar 09 '22 at 09:21
  • I recommend this [article](https://overreacted.io/a-complete-guide-to-useeffect/) – SimonDX Mar 09 '22 at 13:26
0

Is ABCD an object? If so, look for a more specific property value on that object to use inside of useEffect's trigger condition[]. By doing so, if the value does not change, even if useEffect runs through an dependent structure, there will be no circularity.

I am sure that the value of the variable required for fetch, does not keep changing every time when it is fetched again.

If that is the case, please write a more specific code example.

MINJA KIM
  • 876
  • 1
  • 8
  • 22
0

I would remove the dependency on A and B in your first effect. C will only update if A is updated (and subsequently B). So, you will not need to listen for changes to A and B, because their change will be a given.

Try that:

React.useEffect(() => {
   D = fetchReq(A, B, C);
}, [C])

React.useEffect(() => {
   B = fetchReq(A)
}, [A])

React.useEffect(() => {
   C = fetchReq(B)
}, [B])
PsiKai
  • 1,803
  • 1
  • 5
  • 19