Evan
Evan

Reputation: 103

Will setState inside componentWillReceiveProps run before render?

The react docs mention that calls to setState are enqueued, and do not happen immediately. Does react make any guarantees that setState enqueued inside componentWillReceiveProps will execute before the next component render? Are either of these scenarios more likely than the other?

  1. props change > componentWillReceiveProps called > setState enqueued > setState runs > render (which includes new state)

  2. props change > componentWillReceiveProps called > setState enqueued > render > setState runs > re-rendered

Or, are both of these scenarios equally likely? Meaning does React not make any guarantees when setState will run relative to component lifecycle methods?

Here is a ES2015 code excerpt of my example:

import React from 'react';

class Widget extends React.Component {

  componentWillReceiveProps() {
    this.setState({foo: 'bar'});
  }

  render() {
    return <div>
      <a onClick={(e) => {
        e.preventDefault();
        this.props.triggerExternalPropsChange();
      }}>
        Click me to trigger new props
      </a>
    </div>;
  }
}

Where triggerExternalPropsChange passes new props to the Widget component.

Upvotes: 8

Views: 8065

Answers (3)

Dan Abramov
Dan Abramov

Reputation: 268255

The only reason componentWillReceiveProps exists is to give the component an opportunity to setState. So yes, any state you set synchronously in it will be processed together with the new props. There won’t be two renders in this case, just one.

Upvotes: 26

Miloš Rašić
Miloš Rašić

Reputation: 2279

It's 1.

Calling setState() in componentWillReceiveProps() is an exception in the sense of executing state update before the component renders, so you will get both props changes and state changes applied in the same render.

Upvotes: 1

Chase DeAnda
Chase DeAnda

Reputation: 16441

Yep, both are likely. React will try to render anytime it gets new props or state and because it does dom diffing, it tries to render as often as possible. You have options to control it though, using shouldComponentUpdate you can check and wait until both props and state have been updated before rendering.

Upvotes: 0

Related Questions