How to use React setstate() in 5 mins like a pro
Subscribe to TLDRStories.com to get your daily dose of tech news, condensed into a few stories.
When I started ReactJs I had difficulty understanding this.state
and setState()
concept, so I decided to write it on medium to help those who are confused as well. When React state is done correctly it can boost performance and make your code cleaner.
Let’s learn some holy react shit today! 💩
Initialization
Before we use setState()
, we need to initialize it by declaring this.state = {}
with the variables, inside the class constructor.
class Person extends React.Component {
constructor(props, context) {
super(props, context) // init state
this.state = {
name: "Cloud Strife",
age: 24
}
}
}
BasicsetState()
structure for string and integer
class Person extends React.Component {
constructor(props, context) {
super(props, context) // init state
this.state = {
firstName: "Cloud Strife",
age: 24
}
} // set new data
onDetailChange = () => {
this.setstate({
firstName: "Tifa Lockhart",
age: 20
});
}
}
How to use state correctly
Let me explain 3 basic principles for this.state
and setState()
.
- Do not modify the state directly, this will not re-render a component.
// Wrong
this.state.name = 'Cloud';
Use setState()
instead. The only place where you can assign this.state
is the constructor.
// Correct
this.setState({name: 'Cloud'});
2. State Updates May Be Asynchronous
React may batch multiple setState()
calls into a single update for performance.
Because this.props
and this.state
maybe updated asynchronously, you should not rely on their values for calculating the next state.
// wrong
this.setState({
counter: this.state.counter + this.props.increaseValue
});
Arrow function example
this.setState((prevState, props) => ({
counter: prevState.counter + props.increaseValue
}));
Regular function example
// correct
this.setState(function(prevState, props) {
return {
counter: prevState.counter + props.increaseValue
};
});
3. State Updates are Merged
When you call setState()
, React merges the object you provide into the current state.
Your state can contain multiple independent variables.
constructor(props) {
super(props);
this.state = {
name: "Tifa Lockhart",
age: 20
};
};
Then you can update them independently with 2 separate setState()
calls.
// set new name
onNameChange = (newName) => {
this.setstate({
name: newName
})
};
// set new age
onAgeChange = (newAge) => {
this.setstate({
age: newAge
})
};
How to add an item to an array using setState()
- Using destructuring assignment
class People extends React.Component {
constructor(props, context) {
super(props, context)
this.state = {
names: [],
}
} // add new data
onAddNames = (newName) => {
this.setState(prevState => ({
names: [...prevState.names, newName]
}));
}
}
2. Use concat(), not push(). Why?
You cannot mutate this.state directly, it is immutable. So you are not allowed to use push()
to push new data into the existing this.state
array, you will be modifying the this.state
directly if you do so.
Instead, use concat()
which will create and return a new array, therefore the array from this.state
is intact.
// correct
onAddNames = (newName) => {
this.setState(prevState => ({
names: prevState.names.concat(newName)
}));
}// wrong, not allowed
onAddNames = (newName) => {
this.setState(prevState => ({
names: prevState.names.push(newName)
}));
}
Adding a new object into an array using setState()
// add new data object
onAddPerson = (newName, newAge) => {
this.setState(prevState => ({
Person: [
...prevState.person,
{
name: newName,
age: newAge
}
]
}))
}
How to update an item in an array using setState()
Use array.map()
onUpdateName = (deleteName, newName) => {
this.setState(state => ({
files: state.names.map(name => {
if (name === deleteName) {
name = newName
}
return name
})
}))
}
How to delete an item in an array using setState()
Use array.filter()
onDeleteName = (deleteName) => {
this.setState(prevState => ({
names: prevState.names.filter(name => name !== deleteName)
}))
}
How to update multiple values on your form using one function.
I found a new way to make my code a little cleaner…hell yeah. Your function might look like this to update multiple values on your form.
onPasswordChange(event) {
this.setState({ password: event.target.value });
}onEmailChange(event) {
this.setState({ email: event.target.value });
}
Now, just use one function
// callback function on onChange
onFormChange(event) {
const {value, name} = event.target;
this.setState({ [name]: value });
}
Let me show you the entire class and make sure you bind(this)
your function to avoid this error.
TypeError: Cannot read property ‘setState’ of undefined
class Person extends React.Component {
constructor(props, context) {
super(props, context)
this.state = {
email: "",
password: ""
} this.onFormChange = this.onFormChange.bind(this);
} // callback function on onChange
onFormChange(event) {
const { value, name } = event.target;
this.setState({ [name]: value });
}
}
These are the example elements, then initialize onChange={ this.onFormChange }
<input onChange={this.onFormChange} name="email" type="email"/><input onChange={this.onFormChange} name="password" type="password"/>
setState() Callback
Sometimes we want to call a function immediately after all the data has been updated by setState()
. You can do that by adding a callback function to setState()
onNameChange = (newName) => {
this.setState({
name: newName
})
}), () => {
// this is called after setState has updated all the values
})
Tadaaa! You just leveled up in React! Happy reacting or setStating…hahaha! Hoooooray!
Subscribe to TLDRStories.com to get your daily dose of tech news, condensed into a few stories.