Skip to content

Instantly share code, notes, and snippets.

@Knighton910
Last active April 25, 2022 22:38
Show Gist options
  • Save Knighton910/a9e63428b753822a8288dbbf20fff95b to your computer and use it in GitHub Desktop.
Save Knighton910/a9e63428b753822a8288dbbf20fff95b to your computer and use it in GitHub Desktop.
React State in Classes refresh

The state of a React class is a special property that controls the rendering of a page. When you change the state, React knows that the component is out-of-date and will automatically re-render.

The state property is a standard class property, which means

that it is accessible in other methods, not just the render method.

Another important change you made was to create the getTotal() method by assigning an arrow function to a class property. Without using the arrow function, this method would create a new this binding, which would interfere with the current this binding and introduce a bug into our code.

Update State in classes

To update state, React developers use a special method called "setState" that is inherited from the base Component class.

'setState' method takes either an object or function as the 1st arg.

:: Access methods on the class ::

export default class Product extends Component {
  state = {}
  add = () => { ... }
  getTotal = () => { ... }
  render() {
    ...
    <div>Total {this.getTotal()}</div>
    <button onClick={this.add}>Add</button>
  }
}

Arrow funcs methods ensure proper context binding

Notice that you again used an arrow function to create the add method. As mentioned before, this will ensure the function has the proper 'this' context when running the update.

If you add the function as a method without using the arrow function, the setState would not exist without "binding" the function to the current context.

:: Arrow Func ::

add = () => {
  this.setState({
    cart: ['ice cream'],
    total: 5
  })
}

:: This code would produce an error: TypeError Cannot read property 'setState' of undefined :Using an arrow function ensures that you’ll have the proper context to avoid this error.

add() {
    this.setState({
      cart: ['ice cream'],
      total: 5
    })
  }

With the add method, you passed both properties of the state object: cart and total. However, you do not always need to pass a complete object.

You only need to pass an object containing the properties that you want to update, and everything else will stay the same.

Setting State Using Current State

There are many times when you’ll need to reference a previous state to update a current state, such as updating an array, adding a number, or modifying an object.

Another benefit of setting state with a function is increased reliability. To improve performance, React may batch setState calls, which means that this.state.value may not be fully reliable

Take care not to directly mutate state. Instead, when adding a new value to the cart, you can add the new product to the state by using the "...spread syntax" on the current value and adding the new value onto the end.

 add = (product) => {
    this.setState(state => ({
      cart: [...state.cart, product.name],
      total: state.total + product.price
    }))
  }

Removing an item with "setState"

remove = (product) => {
    this.setState(state => {
      const cart = [...state.cart];
      cart.splice(cart.indexOf(product.name))
      return ({
        cart,
        total: state.total - product.price
      })
    })
  }
  // Within the JSX
  <button onClick={() => this.remove(product)}>Remove</button>

To avoid mutating the state object, you must first make a copy of it using the spread operator. Then you can splice out the item you want from the copy and return the copy in the new object.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment