react中setState的用法
setState()更新状态的2种写法
1). setState(updater, [callback]),
updater为返回stateChange对象的函数: (state, props) => stateChange
接收的state和props被保证为最新的
2). setState(stateChange, [callback])
stateChange为对象,
callback是可选的回调函数, 在状态更新且界面更新后才执行
总结:
对象方式是函数方式的简写方式
如果新状态不依赖于原状态 ===> 使用对象方式
如果新状态依赖于原状态 ===> 使用函数方式
如果需要在setState()后获取最新的状态数据, 在第二个callback函数中读取
class Acomponent extends React.Component {
state = {
count: 1
}
test1 = () => {
this.setState(state => ({count: state.count + 1}))
console.log('test1 setState()之后', this.state.count)
}
test2 = () => {
/*const count = this.state.count + 1 //新状态依赖于原状态
this.setState({
count
})*/
this.setState({
count: 3 //新状态不依赖于原状态
})
console.log('test2 setState()之后', this.state.count)
}
test3 = () => {
this.setState(state => ({count: state.count + 1}), () => { // 在状态更新且界面更新之后回调
console.log('test3 setState callback()', this.state.count)
})
}
render() {
console.log('A render()')
return (
<div>
<h1>A组件: {this.state.count}</h1>
<button onClick={this.test1}>A 测试1</button>
<button onClick={this.test2}>A 测试2</button>
<button onClick={this.test3}>A 测试3</button>
</div>
)
}
}
setState()异步OR同步更新
setState()更新状态是异步还是同步的?
1). 执行setState()的位置?
在react控制的回调函数中: 生命周期勾子 / react事件监听回调
非react控制的异步回调函数中: 定时器回调 / 原生事件监听回调 / promise回调 /…
2). 异步 OR 同步?
react相关回调中: 异步
其它异步回调中: 同步
关于异步的setState()
1). 多次调用, 如何处理?
setState({}): 合并更新一次状态, 只调用一次render()更新界面 —状态更新和界面更新都合并了
setState(fn): 更新多次状态, 但只调用一次render()更新界面 —状态更新没有合并, 但界面更新合并了
2). 如何得到异步更新后的状态数据?
在setState()的callback回调函数中
class Bcomponent extends React.Component {
state = {
count: 0,
}
/*
react事件监听回调中, setState()是异步更新状态
*/
update1 = () => {
console.log('update1 setState()之前', this.state.count)
this.setState(state => ({count: state.count + 1}))
console.log('update1 setState()之后', this.state.count)
}
/*
react生命周期勾子中, setState()是异步更新状态
*/
componentDidMount () {
console.log('componentDidMount setState()之前', this.state.count)
this.setState(state => ({count: state.count + 1}))
console.log('componentDidMount setState()之后', this.state.count)
}
/*
定时器回调 / 原生事件监听回调 / promise回调 / 同步更新状态
*/
update2 = () => {
setTimeout(() => {
console.log('setTimeout setState()之前', this.state.count)
this.setState(state => ({count: state.count + 1}))
console.log('setTimeout setState()之后', this.state.count)
})
}
update3 = () => {
const h2 = this.refs.count
h2.onclick = () => {
console.log('onclick setState()之前', this.state.count)
this.setState(state => ({count: state.count + 1}))
console.log('onclick setState()之后', this.state.count)
}
}
update4 = () => {
Promise.resolve().then(value => {
console.log('Promise setState()之前', this.state.count)
this.setState(state => ({count: state.count + 1}))
console.log('Promise setState()之后', this.state.count)
})
}
update5 = () => {
console.log('onclick setState()之前', this.state.count)
this.setState(state => ({count: state.count + 1}))
console.log('onclick setState()之后', this.state.count)
console.log('onclick setState()之前2', this.state.count)
this.setState(state => ({count: state.count + 1}))
console.log('onclick setState()之后2', this.state.count)
}
update6 = () => {
console.log('onclick setState()之前', this.state.count)
this.setState({count: this.state.count + 1})
console.log('onclick setState()之后', this.state.count)
console.log('onclick setState()之前2', this.state.count)
this.setState({count: this.state.count + 1})
console.log('onclick setState()之后2', this.state.count)
}
update7 = () => {
console.log('onclick setState()之前', this.state.count)
this.setState({count: this.state.count + 1})
console.log('onclick setState()之后', this.state.count)
console.log('onclick setState()之前2', this.state.count)
this.setState(state => ({count: state.count + 1})) //当setState第一个参数是函数是,这里的state会是最新的,所以状态更新并没有合并
console.log('onclick setState()之后2', this.state.count)
}
render() {
const {count} = this.state
console.log('render()', count)
return (
<div>
<h2 ref='count'>{count}</h2>
<button onClick={this.update1}>更新1</button> ---
<button onClick={this.update2}>更新2</button>
<button onClick={this.update3}>更新3</button>
<button onClick={this.update4}>更新4</button> ---
<button onClick={this.update5}>更新5</button>
<button onClick={this.update6}>更新6</button>
<button onClick={this.update7}>更新7</button>
</div>
)
}
}