为什么使用setState修改数据
为什么开发过程中不能通过直接修改state的值让页面更新
- 因为直接修改state,React内部并不知道数据发生了变化
- React并没有使用Vue2中的Object.defineProperty或者Vue3的Proxy来监听数据的变化
- 所以必须通过setState来通知React数据发生了变化,需要对页面进行更新
setState 方法是从 React.Component 中继承的:
setState的三种用法
// 一.基本用法
this.setState({
message: "你好,React"
})
// 二.setState可以传入一个回调函数
// 好处一: 回调函数会将之前的state和props传递进来
// 好处二: 可以在回调函数中编写新的state的逻辑
this.setState((state, props) => {
// 1.编写一些对新的state处理逻辑
// 2.可以获取之前的state和props值
console.log(this.state.message, this.props)
return {
message: "你好啊, React"
}
})
// 三.setState是异步的
// 如果希望在数据更新(合并)之后, 获取到对应的结果执行一些逻辑代码
// 可以在setState中传入第二个参数: callback
this.setState(
{ message: "你好啊, React" },
() => {
console.log("++++++:", this.state.message)
}
)
setState是异步更新的
-
setState的更新是异步的?
- 下面代码的打结果是:Hello React
- 课件setState是异步,所以不能在setState之后立刻拿到最新的state的值
changeMessage() {
this.setState({
messaged: '你好啊,React'
})
console.log(this.state.message) //Hello React
}
-
为什么setState的设计是异步的?
- React的核心成员(Redux)的作者 Dan Abramov 在github上的回复
- github.com/facebook/re…
-
setState设计为异步可以显著的提升性能
- 如果每次调用setState都进行一次更新,意味着render函数会被频繁的调用,界面重新渲染,这样效率是很低的
- 最好的方法就是获取到多个更新,进行批量更新
-
如果同步更新了state,但是还没有执行render函数(render函数可能耗时较长),那么state和props不能保持同步, state和prop不能保持一致,会导致很多问题
-
如何获取异步的结果
- 方法一:setState(partialState, callback)的第二个参数,第二参数是一个回调函数,这个回调函数会在更新之后执行
- 方法二:componentDidUpdate(prevProps, preState, snapshot)
setState一定是异步的吗?(React18之前)
分成两种情况:
- 在组件的生命周期或者React合成事件中,setState是异步
- 在setTimeout或者原生DOM事件中,setState是同步的
state = {
message: 'HelloWorld',
}
changeMessage() {
setTimeout(() => {
this.setState({
message: 'Hello React'
})
console.log(this.state.message) //Hello React
}, 0)
}
componentDidMount() {
document.getElementById('btn').addEventListener('click', () => {
this.setState({
message: 'Hello React'
})
console.log(this.state.counter) //Hello React
})
}
setState一定是异步的吗?(React18之后)
在React18之后,默认所有的操作都被放到了批处理中(异步处理)
github自动批处理相关:github.com/reactwg/rea…
如果希望代码可以同步执行(不需要批处理),需要使用flushSync
flushSync(() => {
this.setState({message: 'Hello React'})
})
console.log(this.state.message) //Hello React