The React newbie village

Dealing with the state

Simply put, State is used to modify the internal data of a component. By default, state can only be used in Class components. Thanks to Hooks, we can also use state in function components.

In the previous section we looked at properties props, which can read and render properties in a component. Props

Props cannot be modified

The problem with Props is that it cannot be modified.

Let’s take a look at the following code to see what’s wrong with it:

import React from 'react';

export default  class Element extends React.Component {

  // THIS WON'T WORK
  changeName() {
    this.props.name = 'new name';
  }

  render() {
    return (
      <div>
            <div>{this.props.name}</div>
            <button onClick={()= > this.changeName()} >change</button>
      </div>)}}Copy the code

Failed to modify the name attribute in the previous example! We need to use state to do this.

Create the state

There are two ways to create state:

  • Created in the constructor. Create and initialize state inside the constructor:

    constructor() {
      this.state = {
        cart: [].discounts: []}}Copy the code
  • Create an inline field. In addition to constructors, you can create an inline field and initialize it:

    class Element extends React.Component {
      state = {
        field : 'some value'}}Copy the code

Note that this syntax requires the Babel configuration to support classProperties, see Props

Access to the state

Use this.state to access state, and use the dot operator to access the state property:

this.state.nameOfYourProperty
Copy the code

Deconstruction (ES6 syntax)

When there are multiple attributes to render, we can use the deconstruction syntax to extract multiple attributes. Deconstruction is ES6 syntactic sugar and can be used instead of this.state.something:

  render() {
    return (
      <React.Fragment>
        <div>{this.state.name}</div>
        <div>{this.state.description}</div>
      </React.Fragment>)}Copy the code

Using deconstruction syntax, we can write:

  render() {
    const { name, description } = this.state
    return (
      <React.Fragment>
        <div>{name}</div>
        <div>{description}</div>
      </React.Fragment>)}Copy the code

Note that the following line extracts the attributes you need to use:

const { name, description } = this.state
Copy the code

After extracting the property into the corresponding name and description variables, you can omit the previous this.state.

Note: Does deconstruction grammar smell sweet? The same syntax can be used for this.props.

Change the state

How do I modify state? You can’t manipulate this.state like you did with this.props. It is an error to change this.state directly:

// wouldn't work
this.state.name = 'new value';
Copy the code

You need to use the setState() method to modify state. SetState () is powerful in that it can modify one property or multiple or all properties at once. Initialize attributes, including name and description:

this.state = {
  name: 'initial name'.description: 'initial description'
}
Copy the code

Use setState() to modify some attributes:

this.setState({
  name: 'new name'
})
Copy the code

This directive only modifies the name attribute, leaving the description attribute unchanged.

Note that this operation is asynchronous. If you want to see when setState() is done, you can use the callback function in the second argument:

this.setState({
  name: 'new value'
}, function() {
  // change has happened here
})
Copy the code

Case – Use state

This project will create a component that can modify state. In React, components are divided into stateful components, which can modify state, and stateless components, which only render data.

  1. Git Clone

    git clone https://github.com/softchris/react-starter-project my-component-app
    cd my-component-app
    Copy the code

    The Start project uses webPack to configure the React project based on the tutorial

  2. Run the NPM install command to install dependencies:

    npm install
    Copy the code
  3. Add the person.js file to the SRC directory and add the following:

    import React from 'react';
    
    export default class Person extends React.Component {    
      constructor(props) {
        super(props);  // this call is needed to turn it into a React component
        this.state = {
          name : this.props.name 
        }
      }
    
      changeName(evt) {
        // implement
        console.log(evt);
      }
    
      render() {
        return (
          <div>
            <div>{this.props.name}</div>
            <div><input type="text" onChange={(evt)= > this.changeName(evt)} value={this.state.name} /></div>
          </div>)}}Copy the code

    We’re going to make a component that contains an input field that changes synchronously as we type it.

  4. Find the following code in the index.js file:

ReactDOM.render(
  <div>{title}</div>.document.getElementById('app'));Copy the code

Change to:

ReactDOM.render(
  <Person name={name} />.document.getElementById('app'));Copy the code

Introduce Person at the top of the file:

import Person from './Person';
Copy the code

The above code ensures that the contents of the Person component can be successfully rendered.

  1. Run project NPM start on terminal:

    npm start
    Copy the code
  2. Open your browser and visit http://localhost:8080. View the results:

Now try modifying the input field. Nothing has changed.

We want to modify the contents of the input field as we type it. Now set the contents of the input field to this.state.name:

<input onChange={(evt)= > this.changeName(evt)} value={this.state.name}>
Copy the code

The changeName() method will be called every time we type, but we haven’t added anything to changeName() yet, so we’ll finish it.

  1. Open person.js and change the changeName() method, where state is set:

      changeName(evt) {
        this.setState({
          name: evt.target.value
        })
      }
    Copy the code

    Save and check your browser.

  2. Modify the contents of the input box again.

  3. Update state with the interactive component to ensure that the state is updated every time the user enters, keeping the user input in sync with the component state

Reference code

👉 Example

summary

You learned how to initialize state using constructors and how to modify state properties using setState().