setState()
API
.setState(updater, [callback])
setState()
方法主要是用来更新组件状态,让组件重新渲染。
应该将setState
看作一次请求,而不是直接执行的函数。它内部采用队列处理,调用setState
之后,该次状态被加入到state
的队列中,可能会被成批处理或者推迟处理。
setState
方法一定会导致重新渲染,除非在shouldComponentUpdate()
钩子中返回false
。
陷阱:如果你在setState
执行之后立即获取this.state
,你可能会得setState
调用之前的组件状态。
第一个参数updater:
updater
是一个函数,它接受两个参数:
(preState, props) => newState
preState
:改变之前的state
,不要直接改变该值,使用它构建一个新对象返回。
props
:组件的属性
这里需要注意:使用函数作为参数,返回的新状态也是加入到state
更新队列中,并没有立即被改变。
请看下面例子:
我使用create-react-app
构建了一个reactApp,并修改App.js
中的内容如下:
import React, { Component } from 'react';
import './App.css';
class App extends Component {
state = {
num:0
}
render() {
console.log('---render---')
return (
<div className="App">
<button onClick={this.handleIncrease}>增加</button>
<h3>{this.state.num}</h3>
</div>
);
}
handleIncrease = () => {
this.setState((preState) => ({ num:preState.num + 1 }))
console.log(this.state)
}
}
export default App;
当我点击增加按钮时,控制台打印:
image.png
第一个参数也可以传递一个Object
:
this.setState({ num: this.state.num + 1 })
这是我们最常使用的模式,但是频繁(在同一周期中多次调用)setState
会导致状态合并,只有最后一次生效,继续使用上面的App.js
中的代码:
// 省略部分代码
handleIncrease = () => {
this.setState({ num:2 })
this.setState({ num:4 })
}
查看输出:
image.png
只会应用第二次的状态。
虽然没有执行render
,但是你可以获取到队列中的上一个状态,这就是第一个参数使用函数与对象的区别。
handleIncrease = () => {
this.setState({ num:2 })
this.setState((preState) => { return { num:preState.num + 1 } }
}
image.png
仍然只会渲染一次并使用第二次的setState
的状态。
第二个可选参数[callback]
:
callback
会在setState
执行完成,并且组件重新渲染之后调用。
handleIncrease = () => {
this.setState({ num:2 }, () => {
console.log('callBack')
this.setState({ num:4 })
})
}
查看结果:
image.png
网友评论