The primary way that you make UI updates to your React applications is through a call to the setState()
function. This function will perform a shallow merge between the new state that you provide and the previous state, and will trigger a re-render of your component and all decedents.
Parameters
updater
: It can be an object with a number of key-value pairs that should be merged into the state or a function that returns such an object.callback (optional)
: a function which will be executed after setState()
has been executed successfully. Due to the fact that calls to setState()
are not guaranteed by React to be atomic, this can sometimes be useful if you want to perform some action after you are positive that setState()
has been executed successfully.Usage:
The setState
method accepts an updater
argument that can either be an object with a number of key-value-pairs that should be merged into the state, or a function that returns such an object computed from prevState
and props
.
setState()
with an Object as updater
//
// An example ES6 style component, updating the state on a simple button click.
// Also demonstrates where the state can be set directly and where setState should be used.
//
class Greeting extends React.Component {
constructor(props) {
super(props);
this.click = this.click.bind(this);
// Set initial state (ONLY ALLOWED IN CONSTRUCTOR)
this.state = {
greeting: 'Hello!'
};
}
click(e) {
this.setState({
greeting: 'Hello World!'
});
}
render() {
return(
<div>
<p>{this.state.greeting}</p>
<button onClick={this.click}>Click me</button>
</div>
);
}
}
setState()
with a Function as updater
//
// This is most often used when you want to check or make use
// of previous state before updating any values.
//
this.setState(function(previousState, currentProps) {
return {
counter: previousState.counter + 1
};
});
This can be safer than using an object argument where multiple calls to setState()
are used, as multiple calls may be batched together by React and executed at once, and is the preferred approach when using current props to set state.
this.setState({ counter: this.state.counter + 1 });
this.setState({ counter: this.state.counter + 1 });
this.setState({ counter: this.state.counter + 1 });
These calls may be batched together by React using Object.assign()
, resulting in the counter being incremented by 1 rather than 3.
The functional approach can also be used to move state setting logic outside of components. This allows for isolation and re-use of state logic.
// Outside of component class, potentially in another file/module
function incrementCounter(previousState, currentProps) {
return {
counter: previousState.counter + 1
};
}
// Within component
this.setState(incrementCounter);
setState()
with an Object and a callback function//
// 'Hi There' will be logged to the console after setState completes
//
this.setState({ name: 'John Doe' }, console.log('Hi there'));