ReactJS — useEffect() & useCallback()
In case you never heard about useCallback()
and useEffect()
, I strongly recommend that you check the official docs listed below
- React in general: https://reactjs.org/docs/getting-started.html
useEffect()
: https://reactjs.org/docs/hooks-reference.html#useeffectuseCallback()
: https://reactjs.org/docs/hooks-reference.html#usecallback
In Summary:
useEffect()
useEffect()
is a React Hook which allows you to handle side effects in your functional React components.
You can use it to do anything that doesn’t directly impact your UI/ JSX code (it might eventually affect it, for example, if you’re fetching data from some server, but for the current render cycle, it will not).
useEffect()
allows you to register a function which executes AFTER the current render cycle.
useEffect()
runs after every render cycle (i.e. whenever your functional component re-runs/ re-renders), unless you pass a second argument to an array of dependencies of the effect.
With such a dependency array provided, useEffect()
will only re-run the function you passed as a first argument, whenever one of the dependencies changed.
useCallback()
useCallback()
often is used in conjunction with useEffect()
because it allows you to prevent the re-creation of a function. For this, it's important to understand that functions are just objects in JavaScript.
Therefore, if you have a function (A) inside of a function (B), the inner function (=A) will be recreated (i.e. a brand-new object is created) whenever the outer function (B) runs.
That means that in a functional component, any function you define inside of it is re-created whenever the component rebuilds
Example:
Typically, it’s not a problem, that innerFunction
is re-created for every render cycle.
But it becomes a problem if innerFunction
is a dependency of useEffect()
:
Why is the above code problematic?
The effect re-runs whenever innerFunction
changes. As stated, it is re-created whenever MyComponent
re-builds
Because functions are objects and objects are reference types, that means that the effect will re-run for every render cycle
That might still not be a huge problem, but it is, if innerFunction
does something that causes MyComponent
to re-build (i.e. if it either does something that changes the props or the state).
Now, you would have an infinite loop!
useCallback()
helps you prevent this.
By wrapping it around a function declaration and defining the dependencies of the function, it ensures that the function is only re-created if its dependencies changed.
Hence the function is NOT re-built on every render cycle anymore => You break out of the infinite loop!