To perform cleanup in useEffect Hook, return a function from within the hook. This cleanup function runs before the component unmounts or before the next re-run of useEffect, ensuring any previous side effects are cleared. This is useful for unsubscribing or removing event listeners to prevent memory leaks.
What is the useEffect Hook in React?
Key takeaways:
The
useEffectHook, introduced in React 16.8, allows functional components to handle side effects previously managed in class components.The
useEffectHook helps manage component life cycles by mimicking methods likecomponentDidMount,componentDidUpdate, andcomponentWillUnmount.useEffectcan be used for tasks such as fetching data, manipulating the DOM, handling subscriptions, and performing cleanup operations.The dependencies array in
useEffectdetermines when the effect should be re-run: it runs on every render without dependencies, only once on the initial render with an empty array, and when specific variables change when they are listed in the dependencies array.Cleanup tasks can be performed by returning a function within the
useEffectcallback, which runs before the component unmounts or before the next effect execution.The syntax for using
useEffectisuseEffect(callback, [dependencies]), wherecallbackexecutes the effect and thedependenciesarray controls when it runs.A practical use case for
useEffectis in a chatbox component to load previous messages and indicate the user’s activity when the component first mounts.
Hooks were introduced in version 16.8 of React to enhance functional components, allowing them to manage state and other side effects traditionally handled in class components. One of these powerful Hooks is the useEffect Hook in React functional components.
The React useEffect Hook enables functional components to perform side effects at specific points in a component’s life cycle:
When a component is first rendered (similar to
componentDidMountfunction in class components)When the component updates due to changes in specific values (similar to
componentDidUpdatefunction in class components)Just before the component is removed from the DOM (similar to
componentWillUnmountfunction in class components)
With React useEffect, we can execute side-effect tasks like fetching data in React using fetch API, manipulating the DOM, or subscribing to events. We can also use multiple useEffect Hooks within a component to separate different logic for better readability and maintainability.
If you want to know more about hooks, please look into it: What are React hooks?
Syntax
useEffect(callback, [dependencies]);
In the above syntax:
callbackrefers to the function that runs when theuseEffectHook in React is triggered. This can be an arrow function.dependenciesis an optional array of variables thatuseEffectmonitors. The Hook re-runs only if any of the variables in this array change.
Controlling useEffect Hook with dependencies
The dependencies array in React useEffect determines when useEffect hook should re-run. Here’s how different values for dependencies control the behavior:
Run useEffect on every render
If we want useEffect to execute on every render, simply omit the dependencies array:
useEffect(() => {// This code runs on every render});
Run useEffect only once (on initial render)
To make React useEffect Hook run only once when the component is initially mounted, pass an empty array [] as dependencies. This mimics the componentDidMount method in React class components:
useEffect(() => {// This code runs only on the initial render}, []);
Run useEffect when certain values change
To trigger the useEffect Hook only when specific variables change, include them in the dependencies array. This is similar to componentDidUpdate method in React class components:
useEffect(() => {// This code runs only when variable x changes}, [x]);
Run cleanup code before the component unmounts
To run a cleanup function before the component is removed from the DOM, return a function from within the callback function. This cleanup function in the useEffect Hook runs after the initial render and before every re-run of useEffect, ensuring that any previous side effects are cleared. This functionality is similar to componentWillUnmount method in React class components:
useEffect(() => {// Setup codereturn () => {// Cleanup code that runs before the component unmounts};});
How to use useEffect in a chatbox component
Consider a simple example of a chatbox component in React where we need to load previous messages using the useEffect hook and indicate that the user is active when the chatbox is first opened.
Code explanation
In the above ChatboxComponent.js file:
Lines 5–6: We use the
useStateHook to manage the state of theuserActiveandmessagesvariables. You can explore theuseStateHook in more detail here.Lines 8–29: The
useEffectHook is employed here to perform an asynchronous operation—fetching data on mount—when the component is first rendered.Lines 10–27: Since the callback function in
useEffectHook cannot be directly asynchronous, we define anasyncfunctionretrieveOldMessageswithin the callback and call it immediately. This approach allows us to handle asynchronous tasks like fetching data without issues.Line 28: After the messages are fetched, we set the
userActivestatus totrue, indicating that the user is active in the chat.Line 29: We pass an empty array
[]as the dependencies parameter to ensureuseEffectHook only runs once on the initial render, mimicking thecomponentDidMountmethod in class components.
Common mistakes while using useEffect
Skipping the dependencies array:
Omitting the dependencies array can cause the effect to run after every render, leading to performance issues.
Mutating state inside effects without dependencies:
This can cause an infinite loop of renders.
Incorrect dependencies:
Ensure all variables used in the effect are added to the dependencies array to avoid stale closures.
Best practices
Always include dependencies in the array.
Keep effects focused—one purpose per effect.
Use cleanup functions to avoid memory leaks.
Knowledge test
Let’s attempt a short quiz to assess your understanding.
Which statement about the useEffect Hook in React is true?
The useEffect Hook can only run on the initial render and cannot watch for changes in variables.
The useEffect Hook cannot handle cleanup tasks when a component unmounts.
The useEffect Hook allows functional components to handle side effects similar to life cycle methods in class components.
The useEffect hook can only be used in class components, not in functional components.
Conclusion
The useEffect Hook in React is a powerful tool, enabling React functional components to handle side effects, something previously possible only in class components. By controlling when useEffect runs through the dependencies array, we can effectively manage component life cycles in React functional components, making our code more readable and easier to maintain. Whether we need to fetch data on the component mount, watch for changes in specific variables, or clean up resources when a component unmounts, useEffect Hook offers a flexible and powerful solution for handling side effects in React.
Understanding and mastering useEffect in React allows developers to build dynamic, efficient, and well-structured React applications. As you become more familiar with this Hook, you’ll find it essential for managing side effects and enhancing the interactivity and responsiveness of the React components.
If you want to explore more about React, check out our blog: The best React developer roadmap for 2024, for in-depth insights into the latest React tools and best practices.
Frequently asked questions
Haven’t found what you were looking for? Contact Us
How to perform cleanup in the useEffect Hook in React
What is the best way to fetch data in a React component with useEffect?
When should we avoid using useEffect in React?
Free Resources