DEV Community

Cover image for React Component Lifecycle
Vincent Tong
Vincent Tong

Posted on

React Component Lifecycle

ReactJS is a javascript library used to build user interfaces.

Understanding the life cycle of a component is fundamental in building user-friendly application.

A react component has 4 major phases: Initializing, Mounting, Updating, & Unmounting.

LifeCycle

INITIALIZATION
- The set-up phase where we set the state. It is usually done within the constructor method.

MOUNTING
- The process of placing elements onto the DOM.
- This will be the first time an element will be rendered on a page.

UPDATING
- occurs whenever there is a change to a component's STATE or PROPS.

UNMOUNTING
- As the name implies, this is when a component is REMOVED from the DOM

React Components have methods that, when called, are invoked at certain stages in it's lifecycle. Most of these are optional and for the most part self-explanatory, but serve important functionality.

Lets break it down piece by piece:

INITIALIZATION

  • constructor() - (optional**) Similar as using constructor in JS classes, constructor is used the same way in React passing in 'props' as an argument. Within the constructor scope is the invocation of super(props). Calling super will allow us access to variables from the parent class while passing in props will allow us to pass data from one component to another [3]

**Although a constructor() call is technically optional, you will usually want to call it for two reasons:

  1. to initialize the local state by assigning an object to this.state
  2. to bind an event handler method to an instance [5]
class Example extends React.Component {
    constructor(props) { 
    super(props);
    this.state = {
     };
}
Enter fullscreen mode Exit fullscreen mode

MOUNTING

  • getDerivedStateFromProps() - (optional) called before render. Here we can set the state based on the initial props.[1]
  • componentWillMount() - (optional) called before render. After this method, the component will get mounted.
  • render() - (required) this method is what actually puts our HTML on the page. Once it is run, you will be able to see your component. When changes are made to the props/state this method will be invoked again to re-render the page.
  • componentDidMount - (optional) called after render(). can be used to change the state after it has successfully rendered onto the page.

UPDATING

  • getDerivedStateFromProps() - (optional) same functionality when used in mounting. see above.
  • shouldComponentUpdate() - (optional) returns a boolean. if set to false, the component will not update when a state/prop is changed. If true or not called, it will allow updates to occur. Essentially, this method makes a re-render optional.
  • componentWillUpdate() - accepts two arguments: next props and next state. It is called once after shouldComponentUpdate and before a re-render.
  • getSnapshotBeforeUpdate - (optional) accepts two arguments: previous props, and previous state. It allows the access to any props and stats before the component was updated. If using this method, you are required to have componentDidUpdate() called as well, otherwise there will be bugs on your app.
  • componentDidUpdate() - (optional) called after a component is updated in the DOM [3].

UNMOUNTING

There's only one method that will run when you wish to unmount your component and that is componentWillUnmount()

  • componentWillUnmount() - (required) immediately after removing component from DOM, this will invoke. This denotes the end of a component's lifecycle and is required when properly trying to remove a component from the app.

[1] https://www.w3schools.com/react/react_lifecycle.asp
[2] https://www.javatpoint.com/react-constructor#:~:text=The%20constructor%20is%20a%20method,before%20the%20component%20is%20mounted.
[3]https://www.geeksforgeeks.org/whats-the-difference-between-super-and-superprops-in-react/
[4] https://www.freecodecamp.org/news/how-to-understand-a-components-lifecycle-methods-in-reactjs-e1a609840630/
[5] https://reactjs.org/docs/react-component.html#:~:text=If%20you%20don't%20initialize,props)%20before%20any%20other%20statement.

Discussion (8)

Collapse
joelbonetr profile image
JoelBonetR • Edited on

If I may, I'd like to add documentation using react hooks:

Initialisation will be the base state of your component before it fetches data and/or sets some states etc. The rest can be reduced to a single hook: useEffect as follows:

useEffect(() => {
  console.log("mount & update");

  return () => {
    console.log("cleanup / will unmount");
  };
}, [dependencies?]);
Enter fullscreen mode Exit fullscreen mode

If you set dependencies it will act as update. Without dependencies (empty array) it will execute only on mount life-cycle step. Then

MOUNT

useEffect(() => {
  console.log("mount");
}, []);
Enter fullscreen mode Exit fullscreen mode

This is a perfectly valid code. You can set a hook without unmounting (return) or dependencies.
Also, you can set multiple useEffect hooks for a single component.

UPDATE:

useEffect(() => {
  console.log("update");
}, [myState]);
Enter fullscreen mode Exit fullscreen mode

The useEffect hook will trigger each time "myState" gets changed.

UNMOUNT

componentWillUnmount is used for cleanup (like removing event listeners, cancel the timer etc). Say you are adding a event listener in componentDidMount and removing it in componentWillUnmount as below.

componentDidMount() {
  window.addEventListener('mousemove', () => {})
}

componentWillUnmount() {
  window.removeEventListener('mousemove', () => {})
}
Enter fullscreen mode Exit fullscreen mode

Hook equivalent of above code will look as follows

useEffect(() => {
  window.addEventListener('mousemove', () => {});

  // returned function will be called on component unmount 
  return () => {
    window.removeEventListener('mousemove', () => {})
  }
}, [])
Enter fullscreen mode Exit fullscreen mode

All custom hooks will then use useEffect hook to be defined. You can see examples of custom hooks here .
* Sometimes the ones showed on that site can be optimised either be for performance of for readability.

You can find the complete hooks API here .

Hope it helps somehow πŸ‘ŒπŸ˜

Collapse
sylwiavargas profile image
Sylwia Vargas

Just popping in here to say that we are rewriting the useEffects section of the docs as well as the API reference - stay tuned!

Collapse
lukeshiru profile image
Luke Shiru

One important thing about the functional approach is that we shouldn't be thinking nor designing our components around "lifecycle". React 18 with StrictMode for example runs intentionally your effects twice to break your components if you're using them to catch "mounting" or similar.

Collapse
joelbonetr profile image
JoelBonetR

It just does that in dev time, not in production mode (for obvious reasons).

Even that, React components have lifecycle and some features need to think of those steps and think of them not just for a single component but for the parent + childs for performance concerns, API quota concerns and so on.

Thread Thread
lukeshiru profile image
Luke Shiru

It does that in dev so you address them and fix them πŸ˜… .... they obviously don't do that in production because effects shouldn't run twice. If you think "it doesn't happen in production" you completely missed the point πŸ˜΅β€πŸ’«

You shouldn't design your components thinking in their lifecycle, and even less so use effects for that. I recommend you take a look at the official beta React docs here, and you can follow Dan Abramov's tweet about this topic here.

Thread Thread
joelbonetr profile image
JoelBonetR

Thank you for the references, I'll check them asap :)

Collapse
alaztetik profile image
Alaz Tetik

Hello, it is a good and refreshing article, thank you. Can you suggest any beginner-friendly open source React projects to inspect and even contribute?

Collapse
velouriagreen profile image
Sam

Wonderful work! It completely reactivated my energies