DEV Community

loading...
Cover image for All lifecycles in Class Components (stateful) and similar in Functional Components (stateless) with practical tips in React JS

All lifecycles in Class Components (stateful) and similar in Functional Components (stateless) with practical tips in React JS

omidshahhosseini profile image OmidShahHosseini ・7 min read

Hi, today I’m going to explain the whole lifecycle of the class component also the same in functional components.

What you will learn after reading this article:

  • Execution of lifecycles in Class Components and Functional Components from the beginning to the end
  • How to implement Class Components lifecycles in Functional Components
  • Proper use of lifecycles in the component according to different modes
  • Lifecycle differences in Class Component and Functional Component
  • practical tips about where to call the components and their impact on the implementation of lifecycles
  • And other important and practical cases …

So let’s get started.
At first, we want to answer the question, what is the lifecycle of a component?
The lifecycle of a component in virtually all phases of its implementation from zero to one hundred until the component is fully rendered.
Each phase is suitable for a specific operation and events occur in it. So you should use the right life cycle in your component according to your needs, otherwise, it will cause errors and problems in your program.
So now that we understand these things, we are about to introducing and explaining lifecycles.
The lifecycles of React components are divided into the following 3 sections, each of which will be described below:

  1. Mounting: In this step, your initial states and data are initialized
  2. Updating: In the update section, you can access your states and data, and you can perform update operations on it
  3. Unmounting: And in the last section you can write the operations you want to do before unmounting a component, such as clearing a SetInterval

Lifecycles also include three phases in execution:

  1. Render phase: Pure and has no side effects. Maybe paused, aborted, or restarted by React.
  2. Pre-commit phase: Can read the DOM.
  3. Commit phase: Can work with DOM, run side effects, schedule updates.

well, now you know about the all parts and phase lifecycles of a component. the image below can help you to better understand:

Alt Text

The main lifecycles in the Class Component:
In this section, we begin to introduce the main lifecycles in the class component. The main life cycles are those that are currently in use because a number of other lifecycles are no longer used in react, which we will discuss later.

Lifecycles in Class Components
Alt Text

Mounting Lifecycles in Class Component:
Alt Text

1- Constructor
First of all, you should know that the Constructor method is not a lifecycle. The first thing that runs in the Class Component is the Constructor. The constructor method is a special method for creating and initializing an object created with a class. You should not call setState() in the constructor(). Instead, if your component needs to use a local state, assign the initial state to this.state directly in the constructor. The constructor is the only place where you should assign this.state directly. In all other methods, you need to use this.setState() instead. Avoid introducing any side-effects or subscriptions in the constructor. For those use cases, you must use componentDidMount() instead.

// Example

constructor(props) {
super(props);
console.log(“Constructor”);
this.state = { color: “red”};
}

Alt Text

2- static getDerivedStateFromProps
getDerivedStateFromProps lifecycle runs after the constructor method and before the componentDidMount lifecycle run.
getDerivedStateFromProps is invoked right before calling the render method, both on the initial mount and on subsequent updates. It should return an object to update the state, or null to update nothing.

// Example

static getDerivedStateFromProps(props, state) {
console.log(“GetDerivedStateFromProps”);
return null;
}

Notice: This method exists for rare use cases where the state depends on changes in props over time.

Alt Text

3- componentDidMount
componentDidMount() is invoked immediately after a component is mounted (inserted into the tree). Initialization that requires DOM nodes should go here. If you need to load data from a remote endpoint, this is a good place to instantiate the network request. This method is a good place to set up any subscriptions. If you do that, don’t forget to unsubscribe in componentWillUnmount().
You may call setState() immediately in componentDidMount(). It will trigger an extra rendering, but it will happen before the browser updates the screen. This guarantees that even though the render() will be called twice in this case, the user won’t see the intermediate state. Use this pattern with caution because it often causes performance issues. In most cases, you should be able to assign the initial state in the constructor() instead. It can, however, be necessary for cases like modals and tooltips when you need to measure a DOM node before rendering something that depends on its size or position.

// Example

componentDidMount() {
console.log(“ComponentDidMount”);
}

Updating Lifecycles in Class Component:
In the component update phase, the following 3 lifecycles are executed each time:

Alt Text

1- getDerivedStateFromProps
As we talked about above in this lifecycle, this cycle is executed for the first time after the manufacturer method and it is also the first cycle that is executed first after each update.

// Example

static getDerivedStateFromProps(props, state) {
console.log(“GetDerivedStateFromProps”);
return null;
}

Alt Text

2- getSnapshotBeforeUpdate
getSnapshotBeforeUpdate() is invoked right before the most recently rendered output is committed to e.g. the DOM. It enables your component to capture some information from the DOM (e.g. scroll position) before it is potentially changed. Any value returned by this lifecycle will be passed as a parameter to componentDidUpdate().
This use case is not common, but it may occur in UI like a chat thread that needs to handle scroll position in a special way.
A snapshot value (or null) should be returned.

// Example

getSnapshotBeforeUpdate(prevProps, prevState) {
console.log(“GetSnapshotBeforeUpdate”);
return null;
}

Alt Text

3- componentDidUpdate
This method is not called for the initial render. This is the best lifecycle for DOM and setState updates. This is also a good place to do network requests as long as you compare the current props to previous props.

// Example

componentDidUpdate(prevProps, prevState, snapshot) {
console.log(“ComponentDidUpdate”)
}

Unmounting Lifecycles in Class Component:

And in the end, only one lifecycle runs:
Alt Text

1- componentWillUnmount
componentWillUnmount() is invoked immediately before a component is unmounted and destroyed. Perform any necessary cleanup in this method, such as invalidating timers, canceling network requests, or cleaning up any subscriptions that were created in componentDidMount().
You should not call setState() in componentWillUnmount() because the component will never be re-rendered. Once a component instance is unmounted, it will never be mounted again.

// Example

componentWillUnmount() {
console.log(“componentWillUnmount”);
}

Lifecycles in Functional Components
Alt Text

After knowing the lifecycles in the Class Component and understanding the properties of each, we now move on to how to implement and use them in the Functional Component.
First of all, you should know that you do not need a series of life cycles in the Functional Components and a series of life cycles have not yet been released for Functional Components, which according to the React JS team will be added in the future.
The following is a list of life cycles that you do not need in functional components, and some of them will be added in the future:

1- Constructor
Function components don’t need a constructor. You can initialize the state in the useState call. If computing the initial state is expensive, you can pass a function to useState.

2- getSnapshotBeforeUpdate, componentDidCatch and getDerivedStateFromError
There are no Hook equivalents for these methods yet, but they will be added soon.

Before starting the explanation, you should know that all phases of componentDidMount, componentDidUpdate, componentWillUnmount are implemented by useEffect Hook.

Mounting Lifecycle in Functional Component:
Alt Text

1- Implement componentDidMount in Functional Component
To use and implement the componentDidMount lifecycle you must use the useEffect Hook as follows:
You must use the open and closed bracket at the end before useEffect closes.

// Example

useEffect(() => {
console.log(“ComponentDidMount”);
}, []);

Updating Lifecycles in Functional Component:
Alt Text

1- Implement componentDidUpdate in Functional Component
Note that this cycle is similar to componentDidMount and componentDidUpdate, which means that if you use this lifecycle, in addition to running once in the Mounting phase, it also runs in the Updating phase.
To use and implement this lifecycle you must use the useEffect Hook as follows.

// Example

useEffect(() => {
console.log(“ComponentDidMount & ComponentDidUpdate”);
});

Unmounting Lifecycle in Functional Component:
Alt Text

1- Implement componentWillUnmount in Functional Component
To use and implement the componentWillUnmount lifecycle you must use the useEffect Hook as follows:
You must use the open and closed bracket at the end before useEffect closes. You should also write a return in useEffect.

// Example

useEffect(() => {
return () => {
console.log(“ComponentWillUnmount”);
};
}, []);

Okay, now you know all the life cycles in class components and functional components and you know how to implement them.
In the following section, we will discuss practical points that are important and may even be asked of you in interviews:

  • If the parent component is a class component and its children are a class component and a functional component, first the child class cycle life cycles are executed, then the parent class cycle life cycles are executed, and finally the functional component life cycles.

  • If the parent component is a functional component and its children are a class component and a functional component, first the child class component life cycles are executed, then the child functional component life cycles are executed, and finally the parent functional component life cycles.

  • When each component is updated, only the life cycles of the same component are executed.

  • Only if the component life cycle ends, the componentWillUnmount life cycle of all components runs.

  • When there is a class component and a functional component on a page, does the class component life cycle run first or a functional component?
    answer: First, the class component lifecycles are executed.

  • Does the type of parent component affect the order in which the child components’ life cycles are executed?
    answer: No, the class component and the functional component of the parent component do not affect the order in which the child component life cycles are executed.

There are also three component lifecyclecycles componentDidCatch(), static getDerivedStateFromError(), and shouldComponentUpdate(), which we will discuss in more detail later.

Finally, I hope you enjoyed this article.

Discussion

pic
Editor guide