Skip to content

Instantly share code, notes, and snippets.

@ross-u
Last active December 3, 2020 15:59
Show Gist options
  • Save ross-u/4c6ca7e15eb713cb158bfaee88ace8eb to your computer and use it in GitHub Desktop.
Save ross-u/4c6ca7e15eb713cb158bfaee88ace8eb to your computer and use it in GitHub Desktop.
React - Lifecycle methods

React | Lifecycle methods


Create the project and files

npx create-react-app react-lifecycle-methods

cd react-lifecycle-methods

mkdir src/components

touch src/components/Clock.js

Lifecycle Methods

As your application runs, React is constantly creating and deleting components in memory.

Each class component goes through different phases in its lifecycle:

These 3 phases are:

  • I - Mounting ( component creation )
  • II - Updating ( passing new props or updating state)
  • III - Unmounting (when component is finally destroyed).

Lifecycle methods are special methods available in class components, automatically called by React when our component is Mounting or Updating or Unmounting.

We place our code in the lifecycle methods in order to run it in a certain phase.

img


In Short

Lifecycle methods are special methods that are called automatically by React during the different stages.

These methods exist only in (stateful components) class components.

They are also reffered to as lifecycle hooks. (Different than the new React Hooks API)

  • [ ]

Phases brake down and explanation

I - Mounting or First Render

These methods are called in the following order when an instance of a component is created and inserted into the DOM:

  1. constructor()
  2. render()
  3. componentDidMount()

constructor - Example - gist

class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = { 
      year: props.year
    };
    
    console.log('IN CONSTRUCTOR');
  };
  
	// custom methods and lifecycle methods go after the `constructor`- e.g. `render()`
  
  render() {
    return (
      <div>
        <h1>Clock</h1>
      </div>
    )
  }

}
  • We use it when we want to pass props to the class component.

  • By default it must contain super keyword, that receives props as argument from constructor

  • If we are setting the state in constructor we have to use this keyword

  • We can use it to bind() value of this to the methods

  • If we don’t initialize state from props and we don’t bind methods, we don’t need to implement a constructor for our React component.

  • [ ]


render() - Example - gist

// ...

class Clock extends React.Component {
  constructor(props) {
    // ...
  };
	
  
  
  /* ▩ custom methods and lifecycle methods go after the `constructor` ▩*/
  
  
  render() {
    console.log('IN RENDER');              {/* ADD */}
    
    return (
      <div>
        <h1>Clock</h1>

        <h2>Year</h2>                    {/* ADD */}
        <p>{this.state.year}</p>         {/* ADD */}
      </div>
    );
  }       // ⮕ After`render` is done  the React component “mounts” to the DOM.
}
  • The render() method is next in line lifecycle method called right after the constructor

  • render() is the only required method in a class component

  • The render() function should be pure, meaning that it does not modify component's state.

  • This method structures and prepares the JSX, and returns React elements.

  • After the render is done the React component “mounts” onto the DOM.

  • [ ]


componentDidMount() - Example - gist

//	...

class Clock extends React.Component {
  constructor(props) {
    	// ...
  };
  
  
	// custom methods and lifecycle methods go after the `constructor`
  
  
  componentDidMount() {                      // <-- ADD
    /* our code to run after `render()` is finished and component is mounted onto the DOM */
    
    console.log('IN "COMPONENT DID MOUNT"');                // <-- ADD
  }
  
  
  render() {
    console.log('IN RENDER');
    
    return (
      <div>
        <h1>Clock</h1>

        <h2>Year</h2>
        <p>{this.state.year}</p>
      </div>
    );
  }       
  // ⮕ After`render` is done  the React component “mounts” to the DOM.
}
  • componentDidMount() is called immediately after component render() , after the component is mounted (inserted into the DOM).

  • Since the render() method is already executed, DOM will be already present. Which means that we can reference DOM and our component inside componentDidMount().

  • We shouldn't call setState() here since this will lead to re-rendering of the component (causes performance issues).

  • [ ]


II - Updating

An update can be caused by changes of the props or state.

Update phase is initiated my passing new props, setState() or forceUpdate().

Mounting phase happens only once - when component is created.

Updating phase happens every time when there is a change of the state or the props.


These methods are called in the following order when a component is updated:
  • render() - Invoked by default each time an update happens (new props, setState or forceUpdate)

  • componentDidUpdate()


  • [ ]

componentDidUpdate() - Example - gist

// ...

class Clock extends React.Component {
  constructor(props) {		// 	M1
    //	...
  };
  
  componentDidMount() {		//	M3
    //	...
  }
  
  
  componentDidUpdate(prevProps, prevState) {	//	U2                           // <-- ADD
  /* code to run after update happens via passing new `props`, `setState` or `forceUpdate` */
    
    console.log('IN "COMPONENT DID UPDATE"');                   // <-- ADD
  }
  
  
  render() {	// M2	 U1
    console.log('IN RENDER');

    return (
      <div>
        <h1>Clock</h1>

        <h2>Year</h2>
        <p>{this.state.year}</p>

        <h2>Current Time</h2>                               {/* 	<-- ADD  	*/}
        <p> { this.props.currentTime ? this.props.currentTime : 'LOADING' } </p>
      
       {/* We are passing currentTime by clicking the button in <App /> component */}
      </div>
    );
  }
}

  • componentDidUpdate() is invoked only during the updating phase, immediately after the rerender() is finished.
  • We shouldn’t update the state in componentDidUpdate(). This can cause infinite loop if the proper condition is not set, and it causes an extra re-rendering (affects component performance).
  • componentDidUpdate() gives us access to the props and state from when before the update was made( componentDidUpdate(prevProps, prevState) ).
  • In componentDidUpdate() can do a comparison of prevProps and prevState versus currentthis.props and this.state.to see what exactly changed (if anything) and then react accordingly.

Example

// Check if new props are passed

componentDidUpdate(prevProps) {
   console.log('IN "COMPONENT DID UPDATE"');
  
  // Typical usage - comparing value of the new props:
  if (prevProps.currentTime !== this.props.currentTime) {
    console.log('   RECEIVED NEW PROPS ! ! !');
  }
}

  • [ ]

III - Unmounting

componentWillUnmount() is invoked immediately before a component is unmounted and destroyed (removed from the DOM).

Perform any necessary cleanup in this method, such as invalidating timers, canceling network requests, like for example stopping setInterval() timers before the component gets destroyed and prevent memory leaking .

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.


Exercise


Extra Resources

These are the concepts you should know in React.js (after you learn the basics)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment