Reputation: 973
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?
Upvotes: 1
Views: 1275
Reputation: 51886
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.
Upvotes: 2