Translation: Crazy geek

Original text: blog.logrocket.com/returning-n…

Reproduced without permission

An overview of the

React 16 allows you to decide whether to update.setstate to prevent unnecessary DOM updates. Returning null when calling.setState will no longer trigger the update.

We’ll explore how it works by refactoring a MockTail (a non-alcoholic cocktail) selection program, updating it even if we select the same Mocktail twice.

The directory structure is as follows:

src
 |-> App.js
 |-> Mocktail.js
 |-> index.js
 |-> index.css
 |-> Spinner.js
Copy the code

How does our program work

Our program will display a mockTail selected. You can select or toggle MockTail by clicking a button. A new MockTail is loaded and an image of the MockTail is rendered when the load is complete.

The parent of the App component has the MockTail state and the updateMocktail method, which handles updating the MockTail.

import React, { Component } from 'react';

import Mocktail from './Mocktail';

class App extends Component {

  state = {
    mocktail: ' '
  }

  updateMocktail = mocktail= > this.setState({ mocktail })

  render() {

    const mocktails = ['Cosmopolitan'.'Mojito'.'Blue Lagoon'];

    return (
      <React.Fragment>
        <header>
          <h1>Select Your Mocktail</h1>
          <nav>
            {
              mocktails.map((mocktail) => {
                return <button 
                  key={mocktail}
                  value={mocktail}
                  type="button"
                  onClick={e => this.updateMocktail(e.target.value)}>{mocktail}</button>
              })
            }
          </nav>
        </header>
        <main>
            <Mocktail mocktail={this.state.mocktail} />
        </main>
      </React.Fragment>
    );
  }
}

export default App;
Copy the code

The updateMocktail method is called on the Button element’s onClick event, and the MockTail state is passed to the child component MockTail.

The Mocktail component has a load state called isLoading that renders the Spinner component when it is true.

import React, { Component } from 'react';

import Spinner from './Spinner';

class Mocktail extends Component {

    state = {
        isLoading: false
    }

    componentWillReceiveProps() {
        this.setState({ isLoading: true });
        setTimeout((a)= > 
            this.setState({
                isLoading: false
            }), 500);
    }

    render() {

        if (this.state.isLoading) {
            return <Spinner/>
        }

        return (
            <React.Fragment>
                <div className="mocktail-image">
                    <img src={`img/${this.props.mocktail.replace(/ +/g, "").toLowerCase()}.png`} alt={this.props.mocktail} />
                </div>
            </React.Fragment>
        );
    }
}

export default Mocktail;
Copy the code

Mocktail component componentWillReceiveProps life cycle method invokes the setTimeout, the loading state is set to true to 500 milliseconds.

Each time the MockTail component’s props is updated with a new MockTail state, it displays a load animation for half a second and then renders the MockTail image.

The problem

The problem now is that even if the state has not changed, the MockTail state is updated, triggering a rerendering of the MockTail component.

For example, every time we click the Mojito button, we see the program unnecessarily re-rendering the Mojito image. React 16 improves state performance by preventing updates from being triggered if a new state value is the same as an existing one by returning null in setState.

The solution

Here are the steps we will follow to prevent unnecessary re-rendering:

  1. Check that the new status value is the same as the existing value
  2. If the values are the same, we returnnull
  3. returnnullState updates and component rerenders will not be triggered

First, in the updateMocktail method of the App component, create a constant named newMocktail and assign it a value from the MockTail value passed in.

updateMocktail = mocktail= > {  
  const newMocktail = mocktail;    
  this.setState({     
    mocktail  
  })  
}
Copy the code

Because we need to check and set the state based on the previous state, rather than passing setState and Object, we need to pass a function with the previous state as an argument. Then check that the new value of the MockTail state is the same as the existing value.

SetState will return NULL if the values are the same. Otherwise setState returns the updated MockTail state, which triggers the Rerendering of the MockTail component with the new state.

updateMocktail = mocktail= > {
  const newMocktail = mocktail;  
  this.setState(state= > {
    if (state.mocktail === newMocktail) {
      return null;
    } else {
      return{ mocktail }; }})}Copy the code

Clicking the buttons now still loads their respective MockTail images. However, if we click the same MockTail button again, React will not re-render the MockTail component because setState returns null, so the state is unchanged and the update will not be triggered.

I highlight the update in React DevTools in the two giFs below:

** Note: ** I changed a dark theme here to make it easier to observe updates in the React DOM.

conclusion

React 16 returns NULL from setState. I’ve added the complete code for the MockTail selector for you to use and fork in the CodeSandbox below.

CodeSandbox: CodeSandbox. IO/embed/vj8wk…

Using NULL prevents unnecessary state updates and rerenders, which makes our program run faster and improves the user experience of our program.

People stumble upon our products, and what they think about them is a direct reflection of what they think about the company and its products, so we need to build the experience around their expectations in a natural and intuitive way.

I hope this article has been helpful to you. Thanks for reading!

Welcome to pay attention to the front end public number: front end pioneer, get the front end engineering use kit.