React Component Lifecycle (v.16.13.1)

dieutb
5 min readAug 16, 2020

--

in this section, we will find out the flow rendering of React.

The component Lifecycle

  • mounting: when an instance of a component is created and inserts into the DOM
constructor()UNSAFE_componentWillMount()UNSAFE_componentWillReceiveProps()static getDerivedStateFromProps()render()componentDidMount()
  • updating: props or state change
shouldComponentUpdate()UNSAFE_componentWillUpdate()UNSAFE_componentWillReceiveProps()static getDerivedStateFromProps()render()getSnapshotBeforeUpdate()componentDidUpdate()
  • unmounting: when an instance component is removed from the DOM
componentWillUnmount()

constructor(props)

  • a place to initialize variables, states, event handler (binding this context)
  • run only one time when the instance component is created
  • call super(props) at the beginning of the function
  • don’t call setState() here

shouldComponentUpdate(nextProps, nextState)

  • as default, it always returns true
  • if it returns false, the orther lifecycle will not be invoked
  • In the future, React may treat shouldComponentUpdate() as a hint rather than a strict directive, and returning false may still result in a re-rendering of the component.

static getDerivedStateFromProps(nextProps, prevState)

  • rarely use.
  • invoked right before calling render()
  • is used for applying value props to state
  • return an object to update the state, or null to update nothing
  • if it’s defined, 3 legacies lifecycle will not effect:
    + UNSAFE_componentWillMount()
    + UNSAFE_componentWillUpdate()
    + UNSAFE_componentWillReceiveProps()

getSnapshotBeforeUpdate(prevProps, prevState)

  • invoked right before the element has been rendered/updated
  • capture some information from the DOM before it is potentially changed
  • this output will be the third variable snapshot of componentDidUpdate()
  • is used for capturing and passing the old variable of props and state to componentDidUpdate()

render()

  • a required function
  • invoke when shouldComponentUpdate() is true
  • examine this.props and this.state
  • return:
    + React DOM
    + Arrays React DOM
    + ReactDOM portals (aim to render element in a different position)
    + value of number, string, boolean

componentDidMount()

  • invoke after rendering of the first time
  • a good place to set up any subscriptions/events. don’t forget unsubscriptions in componentWillUnMount()
  • be careful with infinitive loop

componentDidUpdate(prevProps, prevState, snapshot)

  • invoke after rendering from the second time
  • be careful with infinitive loop

componentWillUnmount()

  • invoke when the intance component is removed
  • don’t setState() here

Error Handling: (only use one of above options)

1. static getDerivedStateFromError(error, info)

  • invoke when an error has been thrown
  • is used for logging error and return new state to render error UI

2. componentDidCatch(error, info) # will be deprecate

  • invoke when an error has been thrown
  • is used for logging error and call setState() here to render error UI

Legacy lifecycle method (wouldn’t touch them)

# invoked just before mounting occurs, before render()
UNSAFE_componentWillMount()
# previously named componentWillReceiveProps. work until version 17
UNSAFE_componentWillReceiveProps(nextProps)
# previously named componentWillUpdate. invoked just before rendering when new props or state are being received
UNSAFE_componentWillUpdate(nextProps, nextState)

Reconciliation

  • React’s “diffing” algorithm
  • render() will return a tree of React elements. When we have an update (re-render), React then needs to figure out how to efficiently update the UI to match the most recent tree. React implements a heuristic O(n) algorithm based on two assumptions:
    1. Two elements of different types will produce different trees.
    2. The developer can hint at which child elements may be stable across different renders with a key prop.
  • Whenever the root elements have different types, React will tear down the old tree and build the new tree.
  • If there is the same type but changing attributes, the React only update the attributes.
  • Recursive child: React compare the element with their order. the example below will render new the 3 elements because of the wrong position.
  • To solve this issue, React supports a key attribute

React API

1. setState(updater, [callback])

  • enqueues changes to the component and tells React that this component and its children need to be re-rendered with the updated state
  • setState() will always lead to a render() unless shouldComponentUpdate() returns false
  • the callback invokes after the component is re-rendered
  • In depth: When and why are setState() calls batched inside event-handler?
    + inside a React event handler, they will produce only a single re-render at the end of the event.
    + But it would apply intermediately change when we call them in Promise callback. React 17 would be batched all updates into once, and for a temporary fix please use ReactDOM.unstable_batchedUpdates(function(){...})

2. forceUpdate([callback])

  • skipping shouldComponentUpdate() and force calling render()
  • for child components, trigger the normal lifecycle methods including the shouldComponentUpdate(). Hence, if the shouldComponentUpdate() return false, child wouldn’t re-render.

PureComponent

  • with Component, when call setState, it always leads to render()
  • a useful react component override the shouldComponentUpdate() that helps to shallow detect the change of props
  • shallow detect only finds a change in the first depth level

React.memo([functional Component], areEqual(prevProps, nextProps))

--

--

dieutb
dieutb

Written by dieutb

passion in finding solutions and research some things relate to technical and helpful in life. Also strongly interest in foods, travel, and gentle music :)

No responses yet