Maria Jane Maria Jane - 2 months ago 37
Javascript Question

lifecycle event state and prevState in react.js

Below is a simple counter in react. But I have 3 confusion.


  1. What is state in line 3? that look like a global variable, it make sense if it has
    var
    or
    const
    before it. Is that a lifecycle function/var?

  2. Do I have to import Component from react? I remember I need not to do that in v15.

  3. Where does prevState come from?




import React, { Component } from 'react';

class Counter extends Component {
state = { value: 0 };

increment = () => {
this.setState(prevState => ({
value: prevState.value + 1
}));
};

decrement = () => {
this.setState(prevState => ({
value: prevState.value - 1
}));
};

render() {
return (
<div>
{this.state.value}
<button onClick={this.increment}>+</button>
<button onClick={this.decrement}>-</button>
</div>
)
}
}


Answer

Here is a demo with a commented-out code to give you more information: http://codepen.io/PiotrBerebecki/pen/rrGWjm

1. What is state in line 3? that look like a global variable, it make sense if it has var or const before it. Is that a lifecycle function/var?

state in line 3 is just a property of the Counter component. However the proper way of initialising a state in React using ES6 syntax is as follows:

constructor() {
  super();
  this.state = {
    value: 0
  }
}

React docs: https://facebook.github.io/react/docs/reusable-components.html#es6-classes

The [React ES6 class] API is similar to React.createClass with the exception of getInitialState. Instead of providing a separate getInitialState method, you set up your own state property in the constructor.

2. Do I have to import Component from react? I remember I need not to do that in v15.

You can alternatively just import React and define a class in the following way:

import React from 'react';

class Counter extends React.Component {
...

The below would also allow you to use Component API:

import React, { Component } from 'react';

class Counter extends Component {
... 

3. Where does prevState come from?

The prevState comes from the setState api: https://facebook.github.io/react/docs/component-api.html#setstate

It's also possible to pass a function with the signature function(state, props). This can be useful in some cases when you want to enqueue an atomic update that consults the previous value of state+props before setting any values. For instance, suppose we wanted to increment a value in state:

this.setState(function(previousState, currentProps) {
  return {
     value: previousState.value + 1
  };
});

You will often see however that the state is updated in the following way:

 this.setState({
   value: this.state.value + 1
 });

Full code from my codepen:

class Counter extends React.Component {

  // state = { value: 0 };
  // the state above is just a property of
  // the Counter class, this is not however
  // how to initialise state in React

  // use the below to initialise state
  constructor() {
    super();
    this.state = {
      value: 0
    }
  }

  increment = () => {
    // this.setState(prevState => ({
    //   value: prevState.value + 1
    // })); 
    // use the above or the below

    this.setState({
      value: this.state.value + 1
    });
  };

  decrement = () => {
    // this.setState(prevState => ({
    //   value: prevState.value - 1
    // }));   
    // use the above or the below

    this.setState({
      value: this.state.value - 1
    });
  };

  render() {
    return (
      <div>
        {this.state.value}
        <button onClick={this.increment}>+</button>
        <button onClick={this.decrement}>-</button>
      </div>
    )
  }
}


ReactDOM.render(
  <Counter />,
  document.getElementById('app')
);