join us!
Mountain" , to provide front-end developers with technical information and a series of basic articles. For a better user experience, please move to our official website rookies (160e8020a81dbe https://xhs-rookies.com/ ) to learn and get the latest articles in time.
"Code tailor" , if you are interested in our article or want to make some suggestions, follow "Novices of Xiaohe Mountain" public account, contact us, you can also watch it on WeChat Our article. Every suggestion or approval is a great encouragement to us!
Preface
In this section, we will introduce React
in setState
, hoping to help everyone really understand setState
.
This article will introduce you to the following:
- How to use
setState
- Cannot directly modify
State
setState()
setState
may be an asynchronous update- The merger of
setState
How to use setState
Before introducing setState
, let's take a setState
at a case of 060e8020a82202 to understand how it is used.
Let's show a use case, when clicking a button to change the text, modify the content displayed before the interface:
Case code
import React, { Component } from 'react'
export default class App extends Component {
constructor(props) {
super(props)
this.state = {
message: 'Hello React',
}
}
render() {
return (
<div>
<h2>{this.state.message}</h2>
<button onClick={(e) => this.changeMessage()}>ChangeMessage</button>
</div>
)
}
changeMessage() {
this.setState({
message: 'Hello xhs,your message is changed.',
})
}
}
state
is set in the class constructor, and then if you want to change state
, it is through the setState
function, the main thing of this function is to pass in an object as a parameter, and the object is the value you want to modify. In the above code, when you click ChangeMessage
setState
function will be called, and setState
will call the render
function, and the page will be re-rendered.
After clicking the button, the effect of re-rendering:
Cannot directly modify State
changeMessage
above 060e8020a82438 method to the following.
changeMessage() {
this.state.message = "Hello xhs,your message is changed.";
}
After clicking ChangeMessage
, the page does not change, but state
you will find that state
in message
changed, but the page will not be re-rendered.
The constructor is the only this.state
, and in order to re-render the page, it can only be modified setState
So, we modify the data setState
- When we call
setState
, the re-executesrender
function, according to the latestState
to createReactElement
objects - Again according to the latest
ReactElement
object,DOM
be modified;
changeMessage() {
this.setState({
message: "Hello xhs,your message is changed."
})
}
setState()
setState(updater, [callback])
setState()
state
the changes to the component React
needs to re-render this component and its subcomponents with the updated state
This is the main way to update the user interface in response to event handlers and process server data
setState()
as a request for instead of an immediate component update command. In order to better perceive performance, React
will delay calling it, and then update multiple components through one pass. React
does not guarantee that state
will take effect immediately.
setState()
does not always update components immediately. It will postpone updates in batches. This makes it a hidden danger to read this.state
setState()
In order to eliminate hidden dangers, please use the callback function of componentDidUpdate
or setState
setState(updater, callback)
), both of which can be guaranteed to be triggered after the application is updated.
Parameter one can have two forms
1. Accepted object type
setState(stateChange[, callback])
stateChange
will superficially merge the incoming objects into the new state
, for example, let count +1
this.setState({ count: this.state.count + 1 })
This form of setState()
is also asynchronous, and multiple setState
be batched in the same cycle. count + 1
multiple times in the same cycle, it is equivalent to:
Object.assign(
previousState, // 之前的状态
{count: state.count + 1},
{count: state.count + 1},
...
)
setState()
called later will cover the value of the first setState
called in the same cycle, so the number of commodities will only increase once. If the subsequent state depends on the current state, we recommend using the form of the updater function instead:
this.setState((state) => {
return { count: state.count + 1 }
})
2. Accept function parameters
In our initial state
and not a count
. But now we have a requirement: that is to add a count
in state
, use the object as the first parameter, you will find such a problem.
changeCount () {
this.setState({
count: 0
}) // => this.state.count 是 undefined
this.setState({
count: this.state.count + 1
}) // => undefined + 1 = NaN
this.setState({
count: this.state.count + 2
}) // => NaN + 2 = NaN
}
The results of running the above code does not meet our expectations, we hope count
operating results are 3
, but end up with NaN
. However, it is not uncommon for this subsequent operation to rely on setState
Here naturally leads to setState
, which can accept a function as a parameter. React.js
will setState
the result of the previous 060e8020a82a6d into this function, you can use the result to perform calculations and operations, and then return an object as the object to state
changeCount () {
this.setState((prevState) => {
return { count: 0 }
})
this.setState((prevState) => {
return { count: prevState.count + 1 }
// 上一个 setState 的返回是 count 为 0,这里需要执行 +1 所以当前返回 1
})
this.setState((prevState) => {
return { count: prevState.count + 2 }
// 上一个 setState 的返回是 count 为 1,这里需要执行 +2 所以当前返回 3
})
// 最后的结果是 this.state.count 为 3
}
In this way, the above-mentioned use the last setState
result to perform the effect.
The second parameter is the callback function
setState()
is an optional fallback function, which will be setState
after 060e8020a82b24 completes the merge and re-renders the components. Generally, we recommend using componentDidUpdate()
instead of this method.
Let's add two printing methods to the function changeMessage
in the case.
changeMessage() {
this.setState({
message: "Hello xhs,your message is changed."
},() => {
console.log('callback result: ',this.state.message);
})
console.log('no callback result:',this.state.message);
}
Let's see the result
From the picture we can see
- When
setState
, we can’t get the result we want right away callback
returns the modified result.
Just because we don't get the result we want right away, this is what we will talk about next. may be an asynchronous update .
In this way, we can know the setState
of the second parameter of 060e8020a82d6b, which is to ensure that state
has been modified. That is, the content executed after re-rendering.
setState may be updated asynchronously
Let's look at the following code:
- The final print result is
Hello React
; - It can be seen that
setState
is an asynchronous operation, and we cannot get the lateststate
resultsetState
changeMessage() {
this.setState({
message: "Hello xhs,your message is changed."
})
console.log(this.state.message); // Hello React
}
Why is setState
designed to be asynchronous?
setState
designed to be asynchronous. In fact, there have been a lot of discussionsGitHub
- React core members (Redux author) Dan Abramov also has corresponding reply , you can refer to;
Let's make a brief summary of his answer:
setState
designed to be asynchronous, which can significantly improve performance;- If
setState
is called for an update every time, it means that therender
function will be called frequently and the interface will be re-rendered, which is very inefficient;
Note: The is to get multiple updates and then perform batch updates;
state
updated synchronouslyrender
function has not been executed, thenstate
andprops
cannot be kept synchronized;
Note:state
andprops
cannot maintain consistency, which will cause many problems in the development;
gets the updated value
- The second parameter of setState , a callback function, this callback function will be executed after the update;
changeMessage() {
this.setState({
message: "Hello xhs,your message is changed."
}, () => {
console.log(this.state.message); // Hello xhs,your message is changed.
});
}
Of course, we can also function in the life cycle:
componentDidUpdate(prevProps, provState, snapshot) {
console.log(this.state.message);
}
setState must be asynchronous?
Doubt: setState
must be updated asynchronously?
Verification 1: Update setTimeout
changeText() {
setTimeout(() => {
this.setState({
message: "你好啊,小和山"
});
console.log(this.state.message); // 你好啊,小和山
}, 0);
}
Verification 2: Native DOM
event:
componentDidMount() {
const btnEl = document.getElementById("btn");
btnEl.addEventListener('click', () => {
this.setState({
message: "你好啊,小和山"
});
console.log(this.state.message); // 你好啊,小和山
})
}
In fact, it is divided into two situations:
- In the component life cycle or
React
synthesis event,setState
is asynchronous; - In the event of
setTimeout
or nativedom
setState
is synchronous;
Combination of setState
Consolidation of data
When you call setState()
, React
will merge the object you provided into the current state
Define some data for state
this.state = {
name: 'xhs',
message: 'Hello React',
count: 0,
}
Modifying state
in message
through setState
will not affect name
changeMessage() {
this.setState({
message: "Hello xhs,your message is changed."
});
}
Multiple setState will be merged
For example, we still have a count
attribute, the default is 0
, record the current number:
- After performing the following operations, the final answer is
1
- Multiple
state
were merged
increment() {
this.setState({
count: this.state.count + 1
});
this.setState({
count: this.state.count + 1
});
this.setState({
count: this.state.count + 1
});
}
How can it be done so that count
will eventually become 3
?
increment() {
this.setState((state, props) => {
return {
count: state.count + 1
}
})
this.setState((state, props) => {
return {
count: state.count + 1
}
})
this.setState((state, props) => {
return {
count: state.count + 1
}
})
}
The above code is used, setState
receives a function as the first parameter to solve this problem, and we can get the result we expect.
Preview of the next section
In this section, we have learned the React
in SetState
. In the next chapter, we will continue to learn the React
of controlled and uncontrolled components in 060e8020a83ff5, so stay tuned!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。