Mastering React Functional Components: Hooks, useEffect, and Lifecycle Explained
October 8, 2024
10 Min Read
In React version 16.8, functional components became more powerful with the introduction of hooks.
Functional components in React existed before version 16.8, but they did not have access to lifecycle methods or state. In version 16.8, React introduced Hooks, which allowed functional components to manage state and implement lifecycle behaviors.
Components are the building blocks of a React application, and there are two ways to write them: functional and class-based. Both approaches achieve the same functionality, but many developers prefer using functional components due to their simplicity and the advantages provided by hooks, like useState and useEffect.
Look closer at the lifecycle of functional components in React
The lifecycle of a functional component refers to the stages a component goes through during its existence, from when it is created and added to the DOM—called mounting or mounted—to when the component is updated, and finally to when it is removed from the DOM, known as unmounting.
So, in a functional component in React, there are three main stages: mounting, updating, and unmounted. We handle these stages in our component by using the useEffect hook. First of all, let's understand what useEffect is:
What is useEffect
?
useEffect is a hook in React that allows us to add side effects to our components. Side effects refer to changes in state or behavior that occur as a result of running a function. These changes can include making API requests, modifying global variables, or altering the DOM.
useEffect can be triggered when props or state in a component change, and we can control when it runs by setting dependencies for it.
How can I handle useEffect
?
As I mentioned, you can handle or control useEffect. For example, if you want your useEffect function to run only when the component first renders and not during state or prop changes, that's called the mounting stage. If you want your useEffect to run only when one of your props or state changes, that’s the updating stage. Lastly, if you want your useEffect to run right before your component is removed from the DOM, that’s the unmounting stage. To manage these stages effectively, you need to understand each step. Let's dive in
What is the mounting stage?
The mounting stage refers to when a component is created or inserted into the DOM (Document Object Model). During this stage, the component renders, the initial state values are set, and any side effects related to mounting are performed.
How can I implement mounting in useEffect
?
If you want your useEffect to run when the component is created and only run once, you can add a second argument to your useEffect hook, which should be an empty array. This setup ensures that your useEffect will run only during the initial render.
Example: Imagine you need a list in your component, and you want it to be fetched for the first time when the component is created. You can add an empty array as the second argument in your useEffect to achieve this.
What is the updating stage?
The updating stage occurs when a component's props or state are updated, resulting in the component being re-rendered. During this stage, the UI updates, and any side effects related to the updating process will run.
How can I implement updating in useEffect
?
To run useEffect when a component is updated, similar to the mounting stage, you need to add an array as the second argument. However, this array should not be empty—you need to include the specific state or props that should trigger the useEffect when they are updated.
Example: Imagine you have a search state in your component that triggers when the user types in the search input. Whenever the user types a letter, you want useEffect to trigger and fetch data from an API based on the user's search. You can implement this by using the updating stage, adding the search state as a dependency in the useEffect hook.
What is the unmounting stage?
This stage occurs when a component is cleared or removed from the DOM, allowing you to clean up resources or perform tasks to prevent memory leaks.
How can I implement unmounting in useEffect
?
To implement unmounting in your component, you can return another function from your useEffect. This function is called the cleanup function, and it runs either right before the component is removed from the DOM or before the useEffect is executed again. This means the cleanup function can also run during the updating stage.
Example: Imagine you have a component that establishes a WebSocket connection or an API stream in the mount stage. To avoid unnecessary connections, you would want to clean up the connection when unmounting or when the component re-renders, as this can cause memory leaks. For this example, you should use a cleanup function to close the WebSocket or stop the API stream.
Check out this cool video on YouTube about this article: