Will React rerender if I use setState but the state value stay the same?

Tags: ,



Say I have a React component with state {random: 1} currently. If I call

this.setState({random: 1})

does it trigger re-rendering? If it does, is there any way I can prevent the re-rendering when calling setState but the state does not change like this?

Answer

Yes, it will re-render:

class App extends React.Component {
  state = { random: 1 };
  render() {
    console.log('rerendering');
    return (
      <button onClick={() => this.setState({random: 1})}>
        click
      </button>
    );
  }
};

ReactDOM.render(<App />, document.querySelector('.react'));
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
    <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div class='react'></div>

You can add a shouldComponentUpdate method to tell React not to re-render if the random value is the same:

class App extends React.Component {
  state = { random: 1 };
  render() {
    console.log('rerendering');
    return (
      <button onClick={() => this.setState({random: 1})}>
        click
      </button>
    );
  }
  shouldComponentUpdate(nextProps, nextState) {
    return nextState.random !== this.state.random;
  }
};

ReactDOM.render(<App />, document.querySelector('.react'));
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
    <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div class='react'></div>

As Artem notes, another option (which is probably better!) is to use a PureComponent instead. From the docs:

React.PureComponent is similar to React.Component. The difference between them is that React.Component doesn’t implement shouldComponentUpdate(), but React.PureComponent implements it with a shallow prop and state comparison.

If your React component’s render() function renders the same result given the same props and state, you can use React.PureComponent for a performance boost in some cases.



Source: stackoverflow