Explain the Lifecycle of a React Component
February 14, 2023
Understanding the React Lifecycle is not only one of the most basic concepts of learning React, but it is also a classic interview question. This article will introduce the three major lifecycle phases and the commonly used lifecycle methods in Class Component.
React component lifecycle is divided into three stages: mounting, updating and unmounting. If you are using a class component, we can use the methods provided by React to execute code during the lifecycle of the component. The following are some common methods to operate the component's lifecycle. (Note that these methods are lifecycle methods for class components. If you use functional components, the concept is different.)
Lifecycle: Mounting, Updating, and Unmounting
Mounting
When React first renders the component and adds the rendered node to the DOM, we call it mounting. After React adds the node to the DOM, the browser renders and draws the page. At this stage, the lifecycle will call these methods in the following order:
Updating
After mounting, if a component's props or state changes, it will trigger a re-render. After the re-render, React will compare which parts of the virtual DOM have changed and then update the changed parts to the actual DOM. We call this stage updating. When a component is re-rendered, its lifecycle will call these methods in the following order:
static getDerivedStateFromProps()
shouldComponentUpdate()
render()
getSnapshotBeforeUpdate()
componentDidUpdate()
Unmounting
When a component is removed from the DOM, we call it unmounting. At this time, the following method will be called:
Render and Commit
In the three different lifecycle phases of Mounting, Updating, and Unmounting, we further divide them into two stages: Render
and Commit
. We use these three stages to re-examine the lifecycle we just discussed.
Mounting
In the rendering stage of mounting, React will call the root component and render the component. If there are other child components in the component, React will recursively render them. It should be noted that to achieve the concurrent feature, the rendering stage may be paused, stopped, or restarted by React (for example, if another component's priority is higher, React will pause the less important one and render the more important one first, and then come back to render the less important one). To ensure that the pause and restart do not affect the rendering results, React's component must be a pure function, meaning that it cannot have side effects and must return the same results every time it is called.
That's why if we want to use side effects in React, we must put them in the componentDidMount
lifecycle method (or useEffect
hook), and ensure that the rendering is a pure function with no side effects. After mounting is completed, the side effects will be executed through componentDidMount
. For more information about pure functions, please refer to the article "What Is a Pure Function? Why Do React Function Components Need to Be Pure?".
In the commit phase of mounting, React uses the appendChild()
DOM API to add the rendered result to the DOM and display it on the screen.
Updating
During the updating phase, React triggers the update of the component by invoking its render method. This process is recursive and if the called component returns another component, React will keep calling components until there are no more to return.
Once the render phase is completed, React compares the previous and current versions of the virtual DOM to identify the differences, and applies only those changes to the actual DOM in the commit phase. As with mounting, it is important to ensure that no side effects are present during the updating phase, and to use the componentDidUpdate()
lifecycle method (or useEffect
) for this purpose.
Pre-commit Phase
However, in the updating phase, there's also a pre-commit phase, which happens before committing the updated result to the actual DOM. If you're using a class component, the getSnapshotBeforeUpdate()
method will be triggered during this phase. This method allows you to extract information from the DOM before it's changed (such as scroll position). The reason for this is that if there are asynchronous operations during the rendering phase, changes might not happen immediately between the render and commit phases. If a user makes changes in this interval, the DOM information obtained through componentWillUpdate()
might not be accurate. Therefore, the getSnapshotBeforeUpdate()
method helps to provide more accurate information to developers.
getSnapshotBeforeUpdate()
is rarely used, except when you need to perform animation-related operations. Furthermore, if you're using a functional component, React currently doesn't provide a corresponding Hook method to simulate it. (For more information, see this discussion).