setState
setState(updater, [callback])
- setState() 将对组件 state 的更改排入队列,并通知 React 需要使用更新后的 state 重新渲染此组件及其子组件。这是用于更新用户界面以响应事件处理器和处理服务器数据的主要方式
- 将 setState() 视为请求而不是立即更新组件的命令。为了更好的感知性能,React 会延迟调用它,然后通过一次传递更新多个组件。React 并不会保证 state 的变更会立即生效。
- setState() 并不总是立即更新组件。它会批量推迟更新。这使得在调用 setState() 后立即读取 this.state 成为了隐患。为了消除隐患,请使用 componentDidUpdate 或者 setState 的回调函数(setState(updater, callback)),这两种方式都可以保证在应用更新后触发
updater
- 用法1函数
(state, props) => stateChange
state 是对应用变化时组件状态的引用。当然,它不应直接被修改。你应该使用基于 state 和 props 构建的新对象来表示变化
export default class test4 extends Component {
constructor(props) {
super(props)
this.state = {
count: 0
}
}
add() {
this.setState((state, props) => {
console.log("之前的:", state.count)
return { count: state.count + 1 }
})
}
render() {
return (
<div>
<p>数值:{this.state.count}</p>
<Button onClick={this.add.bind(this)}>加一</Button>
</div>
)
}
}
- 用法2对象
add() {
this.setState({
count: this.state.count + 1
})
}
两种方式都可以修改状态,但是方式一可以获取之前的状态这是方式二不具备的
callback
callback是一个回调函数,在setState的异步操作结束并且组件已经重新渲染的时候执行。也就是说,我们可以通过这个回调来拿到更新的state的值。
export default class test4 extends Component {
constructor(props) {
super(props)
this.state = {
count: 0
}
}
add() {
this.setState({
count: this.state.count + 1
})
console.log(this.state.count)
}
render() {
return (
<div>
<p>数值:{this.state.count}</p>
<Button onClick={this.add.bind(this)}>加一</Button>
</div>
)
}
}
从图中可以看出,虽然页面上的值已经改变了,但是通过this.state
获取的值还没有更新。如果这时要使用这个值会存在问题。为了解决这个问题,这里可以使用setState的第二个参数回调函数
add() {
this.setState({
count: this.state.count + 1
}, () => {
console.log(this.state.count)
})
}
更新对象
突然发现了一个问题,如果我要更新对象,应该怎么操作
export default class test4 extends Component {
constructor(props) {
super(props)
this.state = {
state1: {
count: 0
}
}
}
add() {
this.setState({
state1: {
...this.state.state1,
count: this.state.state1.count + 1
}
})
}
render() {
return (
<div>
<p>数值:{this.state.state1.count}</p>
<Button onClick={this.add.bind(this)}>加一</Button>
</div>
)
}
}
//方式二
add() {
let data = this.state.state1
data.count = this.state.state1.count + 1
this.setState({
state1: data
})
}
感觉第二种方式更舒服一些
forceUpdate
forceUpdate:强制刷新。
默认情况下,当组件的state或props改变时,组件将重新渲染。如果你的render()方法依赖于一些其他的数据,你可以告诉React组件需要通过调用forceUpdate()重新渲染。
forceUpdate就是重新render。有些变量不在state上,当时你又想达到这个变量更新的时候,刷新render;或者state里的某个变量层次太深,更新的时候没有自动触发render。这些时候都可以手动调用forceUpdate自动触发render
实例
export default class test4 extends Component {
constructor(props) {
super(props)
this.count = 0;
}
add() {
this.count += 1
console.log(this.count)
}
render() {
return (
<div>
<p>数值:{this.count}</p>
<Button onClick={this.add.bind(this)}>加一</Button>
</div>
)
}
}
add() {
this.count += 1
this.forceUpdate()
console.log(this.count)
}
这样做是不推荐的,响应式变量应该定义在state
中,而不是通过强制刷新,来重新渲染页面