DEV Community

hmintoh
hmintoh

Posted on • Updated on

Component lifecycles with React hooks

Before the release of Hooks, React components were divided into 2 broad categories:

  1. Functional components → Stateless components; unable to access lifecycle methods
  2. Class components → Stateful components; able to define states and access lifecycle methods

This meant that the only way to access lifecycle methods was to write the component as a Class. With the introduction of React hooks, it is now possible to create stateful components without the use of a Class.

First, a quick recap of React lifecycles:

Mounting

This is the first lifecycle of a React component, the stage where it is created and inserted into the DOM. In class components, we have the componentDidMount method, which allows us to use setState to modify our states after the first render.

componentDidMount() {
  console.log("The component has mounted successfully!");
  this.setState({isLoading: false});
}
Enter fullscreen mode Exit fullscreen mode

Updating

This lifecycle happens after a component is mounted and rendered into the DOM. The component is updated when we have an update in our props or state. The componentDidUpdate method is invoked after the update happens in the component and is used to compare whether a specified prop or state has changed.

componentDidUpdate(prevProps) {
  if (this.props.name !== prevProps.name) {
    console.log("Name has changed!");
  }
}
Enter fullscreen mode Exit fullscreen mode

Unmounting

This lifecycle is responsible to do the cleanup in our DOM i.e. when we want to remove the component. The componentWillUnmount method is invoked when the component is about to be removed from the DOM:

componentWillUnmount() {
  console.log("Component will be unmounted!");
}
Enter fullscreen mode Exit fullscreen mode

useEffect vs. Lifecycle methods

In class components we have lifecycle methods to perform actions in a specific lifecycle stage of a component. For functional components, we can use the useEffect hook to achieve the same outcomes. The hook has the following signature:

import { useEffect } from 'react';

useEffect(() => {
  // inside this callback function we perform our side effects
});
Enter fullscreen mode Exit fullscreen mode

It receives a callback function as the first argument, which, just like lifecycle methods, will be called after every render.

The second argument (optional) is an array of dependencies that the hook is going to watch i.e. the hook will only run if one of those dependencies change.

This means that when you pass an empty array to the useEffect hook, it will only run once after render.

  • Mounting - Just by using the useEffect hook, we are performing the equivalent of the componentDidMount method:
useEffect(() => {
  console.log("The component has mounted successfully!");
  setisLoading(false);
}, []);
Enter fullscreen mode Exit fullscreen mode
  • Updating - By passing an array of dependencies that we want to watch, the hook will update when any of the dependencies change. For example, if you have a prop name count that is passed into the useEffect hook, the hook will only run when count changes.
useEffect(() => {
  console.log("You have clicked ${count} times")
}, [count]);
Enter fullscreen mode Exit fullscreen mode
  • Unmounting - We return a function within the callback function of the hook, which will achieve the same outcome as a componentWillUnmount method.
useEffect(() => {
  console.log("You have clicked ${count} times")
  return () => console.log("Component will be unmounted!");
}, [count]);
Enter fullscreen mode Exit fullscreen mode

To recap:

  • Up until React 16.8, functional components were stateless and could not access lifecycle methods. With the introduction of hooks, we are now able to add state and perform side effects to our functional components.

  • The useEffect hook is a function that allows us to perform side effects in our functional components. It receives a callback function as its first argument → we define our effects here.

  • The second argument (optional) is an array of dependencies that the hook is going to watch. If you pass an empty array, the hook will not be watching any dependencies and therefore will only run once after the initial render.

  • If you don't pass a second argument into the hook, the effect will run after every render 🤪

learned

Thoughts? Feedback? Let me know in the comments below 👇🏻

Top comments (0)