lifecycle event state and prevState in react.js
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. Another 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 developers updating state in the following way. This is less reliable than the above method as state may be updated asynchronously and we should not rely on its values for calculating the next state.
this.setState({
value: this.state.value + 1 // prone to bugs
});
Full code from my codepen:
class Counter extends React.Component {
// state = { value: 0 };
// you can also initialise state in React
// in the constructor:
constructor() {
super();
this.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>
)
}
}
ReactDOM.render(
<Counter />,
document.getElementById('app')
);
There are some features in your code that are related with the ES6 (ES2015) version, so that's why you might be confused:
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?
As it is inside a class
body, this is not a global variable. In this case state
is a property that will be set to the instances of Counter
, so you could access that by this.state
.
Do I have to import Component from react? I remember I need not to do that in v15.
When creating a component using a class, you need to extend the Component
class, so in this case: yes you need to import Component
or you could've used class Counter extends React.Component
as well.
Where does prevState come from?
Again, a ES6 feature. What is being passed to the this.setState()
method is a function. It might be confusing because this is a arrow function =>
. So previousState
is actually a parameter of that function. To help you to see the picture, the above code is similar to that:
this.setState(function (prevState) {
return {
value: prevState.value - 1
};
});
There are some differences between 'normal' and an arrow functions, though, so I suggest you to search for the ES6 features in order to be more familiar with it.