react基础(八)— setState

165 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 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,但是页面没有重新渲染。 image.png 我们通过setState进行修改。

  increment() {
    // this.state.counter += 1
    // console.log(this.state.counter);
    this.setState({
      counter: this.state.counter + 1
    })
  }

我们可以看到,点击按钮之后数据进行了更新并且重新渲染页面。

image.png

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。

image.png 点击按钮后,页面上的数据进行了更新,变成了hello react,但是打印出来的数据仍然是hello world。

image.png 可以看到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。

image.png 方法二: 在生命周期componentDidUpdate中获取

  componentDidUpdate() {
    console.log(this.state.message);
  }

同样,我们点击按钮后打印出了最新的数据hello react。

image.png