1

I have a scenario where our application has multiple functions that sit within componentDidUpdate. In each of the functions they check to see if their specific data is updated. For example:

componentDidUpdate(prevProps) {
 this.handleFoo(prevProps)
 this.handleMoreFoo(prevProps)
}

handleFoo(prevProps){
  if(this.props.foo != prevProps.foo){
    //Do Something
 }
}

handleMoreFoo(prevProps){
  if(this.props.moreFoo != prevProps.moreFoo){
    //Do Something
 }
}

I have been looking at the useEffect hook and was wondering if I could chop out that initial check in each of these functions and utilize the [] in useEffect and only call one of these functions if their specific key is updated like this:

useEffect(() => {
   if(fooKey){ handleFoo() }
   if(moreFoo) { handleMoreFoo() }
 }, [fooKey, moreFooKey])

Is this possible? Is this advisable?

Grant Herman
  • 923
  • 2
  • 13
  • 29
  • 1
    Call `useEffect()` for each `handleX()` you had prior. The great thing about hooks is that they can function independently of each other and _don't_ need to share a common entry point like the lifecycle methods in the class components. – Patrick Roberts Nov 05 '19 at 18:42
  • Possible Duplicate of [Should I use one or many useEffect in component?](https://stackoverflow.com/questions/54002792/should-i-use-one-or-many-useeffect-in-component/54004148#54004148) – Shubham Khatri Nov 05 '19 at 18:48

1 Answers1

2

Here's how you'd accomplish what you had before, using hooks in a functional component.

I'd define a custom hook to mimic componentDidUpdate(), based on the answer to Make React useEffect hook not run on initial render:

function useUpdate (effect, deps) {
  const firstUpdate = useRef(true);
  const update = useCallback(() => {
    if (firstUpdate.current) {
      firstUpdate.current = false;
    } else {
      return effect();
    }
  }, [firstUpdate, effect]);

  useLayoutEffect(update, deps);
}

...

useUpdate(handleFoo, [fooKey]);
useUpdate(handleMoreFoo, [moreFooKey]);

useLayoutEffect() ensures that the handleX() callbacks are invoked at the same phase of each render as the analogous componentDidMount() and componentDidUpdate() lifecycle methods. If you don't care about the exact phase in which they're invoked, you can replace useLayoutEffect() with useEffect().

The rest of the custom hook ensures that it skips calling the handleX() callbacks after the initial render. If your handleX() callbacks can be called after the initial render, then you can just call useEffect() directly in your functional component instead of this useUpdate() custom hook.

Patrick Roberts
  • 49,224
  • 10
  • 102
  • 153
  • hey is there a way to make sure that the hooks fire in the same order this way? I see now that that is a hard rule of hooks. – Grant Herman Nov 05 '19 at 22:09
  • 1
    @GrantHerman fire in the same order? They'll fire in the order the hooks are instantiated. Does that answer your question? – Patrick Roberts Nov 05 '19 at 22:31