一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第8天,点击查看活动详情。
前言
大家好呀,我是L同学。在上篇文章react基础(七)— 跨组件通信中,我们讲到了使用context进行跨组件通信。在本篇文章中,我们将学习到react中重要的更新数据方法——setState。
setState
在react中,我们想要修改数据,不能直接通过state修改数据,因为我们修改state之后,希望react根据最新的数据重新渲染页面,但是这种方式进行修改react不知道数据发生了变化。 我们需要通过setState来修改数据,告诉react数据已经发生变化了,然后react会根据最新的数据重新渲染页面。
我们并没有组件中实现setState方法,为什么还可以调用它呢?因为setState方法是从Component中继承过来的。
点击按钮时,直接在事件中通过state修改数据,会怎么样呢?我们通过代码来看下。
import React, { Component } from 'react'
export default class App extends Component {
constructor(props) {
super(props)
this.state = {
counter: 0
}
}
render() {
return (
<div>
<h2>当前计数:{this.state.counter}</h2>
<button onClick={e => this.increment()}>+1</button>
</div>
)
}
increment() {
this.state.counter += 1
console.log(this.state.counter);
}
}
我们可以看到此时数据已经发生了更新,变成了1,但是页面没有重新渲染。
我们通过setState进行修改。
increment() {
// this.state.counter += 1
// console.log(this.state.counter);
this.setState({
counter: this.state.counter + 1
})
}
我们可以看到,点击按钮之后数据进行了更新并且重新渲染页面。
setState异步更新
我们来看下通过setState改变数据后,然后打印state的值是什么。
import React, { Component } from 'react'
function Home(props) {
return <h1>{props.message}</h1>
}
export default class App extends Component {
constructor(props) {
super(props)
this.state = {
message: 'hello world'
}
}
render() {
return (
<div>
<h2>当前文本: {this.state.message}</h2>
<button onClick={e => this.changeText()}>改变文本</button>
<Home message={this.state.message}></Home>
</div>
)
}
changeText() {
this.setState({
message: 'hello react'
})
console.log(this.state.message);
}
}
我们可以看到刚开始数据是hello world。
点击按钮后,页面上的数据进行了更新,变成了hello react,但是打印出来的数据仍然是hello world。
可以看到setState是异步操作,我们并不能在执行完setState之后立马拿到最新的state数据。
setState设计为异步,可以显著提高性能。如果每次调用setState都进行一次更新,那么render函数会被频繁调用,重新渲染页面,这样造成效率很低。最好的方法是获取到多个更新,然后批量进行更新。如果同步更新了state,但是还没有执行render函数,会造成state和props不能同步,会在开发中产生很多问题。
那么我们怎么样才能获取到更新后的数据呢?
方法一:setState的回调 setState接收两个参数,第一个参数是更新的state,第二个参数是回调函数,这个函数会在更新之后执行。
changeText() {
this.setState({
message: 'hello react'
}, () => {
console.log(this.state.message);
})
}
我们可以看到点击按钮后打印出来的是hello react。
方法二: 在生命周期componentDidUpdate中获取
componentDidUpdate() {
console.log(this.state.message);
}
同样,我们点击按钮后打印出了最新的数据hello react。