No conoce el setState () de React para actualizar datos de forma asíncrona y su solución

¡Trabajar juntos para crear y crecer juntos! Este es el día 21 de mi participación en el "Nuevo plan diario de Nuggets · Desafío de actualización de agosto", haga clic para ver los detalles del evento

1. Descripción de setState()

Creo que todo el mundo usa mucho React, pero ¿sabes que el método setState() de React actualiza los datos de forma asíncrona? A continuación, usaremos un ejemplo para analizar cómo setState() actualiza los datos de forma asíncrona y a qué se debe prestar atención durante el uso.

1.1 Actualizar datos

setState() actualiza los datos de forma asíncrona

Como todos sabemos, React usa setState() para actualizar los datos, pero de hecho, setState() actualiza los datos de forma asíncrona. El código es el siguiente:

// 导入ract
import React from 'react'
import ReactDOM from 'react-dom'

// App组件
class App extends React.Component {
  // 默认状态的值
  state = {
    count: 1
  }
  
  handleClick = () => {
    // 异步更新state
    this.setState({
      count: this.state.count + 1
    })
    console.log(this.state.count)// 1
    
  }
  
  render() {
    return (
      <div>
        <h1>计数器:{this.state.count}</h1>
        <button onClick={this.handleClick}>+1</button>
      </div>
    )
  }
}

ReactDOM.render(<App />, document.getElementById('root'))
复制代码

En el código anterior, tenemos un valor predeterminado de 1 y proporcionamos un controlador para el evento de clic, cuando se hace clic en el botón una vez, hacemos +1 en ese valor predeterminado, lo que hace que el valor cuente 2, pero porque imprimimos este estado. .count directamente después del método this.setState(), entonces el valor que realmente obtenemos sigue siendo 1, lo que indica que aunque la llamada al método this.setState() ha terminado, el estado no se actualiza inmediatamente, lo que también prueba que this.setState () actualiza los datos de forma asíncrona. El efecto de demostración es el siguiente:

1.gif

Nota: Al usar esta sintaxis, el siguiente setState() no debe depender del setState() anterior

De hecho, se puede llamar a this.setState() varias veces, pero dado que this.setState() actualiza los datos de forma asíncrona, la segunda llamada a this.setState() se llama después de la primera llamada a this.setState(). El resultado no cambiará . el código se muestra a continuación:

// 导入ract
import React from 'react'
import ReactDOM from 'react-dom'

// App组件
class App extends React.Component {
  state = {
    count: 1
  }

  handleClick = () => {
    // 前面的setState()
    this.setState({
      count: this.state.count + 1// 1 + 1
    })
    console.log('第一次调用完的count:', this.state.count)// 1

    // 后面的setState()
    this.setState({
      count: this.state.count + 1
    })
    console.log('第二次调用完的count:', this.state.count)// 1
  }

  render() {
    return (
      <div>
        <h1>计数器:{this.state.count}</h1>
        <button onClick={this.handleClick}>+1</button>
      </div>
    )
  }
}

ReactDOM.render(<App />, document.getElementById('root'))
复制代码

El efecto es el siguiente:

2.gif

setState() se puede llamar varias veces, pero solo se llamará a una nueva representación

Aunque this.setState() se llama dos veces, render() solo se ejecuta una vez (no se cuenta durante la inicialización, solo después de hacer clic en el botón), esto es para un mejor rendimiento y no tendrá que restablecerse cada vez que el estado cambios Renderizar la página. el código se muestra a continuación:

// 导入ract
import React from 'react'
import ReactDOM from 'react-dom'

// App组件
class App extends React.Component {
  state = {
    count: 1
  }

  handleClick = () => {
    // 前面的setState()
    this.setState({
      count: this.state.count + 1// 1 + 1
    })
    console.log('第一次调用完的count:', this.state.count)// 1

    // 后面的setState()
    this.setState({
      count: this.state.count + 1
    })
    console.log('第二次调用完的count:', this.state.count)// 1
  }

  render() {
    console.log('render调用')
    return (
      <div>
        <h1>计数器:{this.state.count}</h1>
        <button onClick={this.handleClick}>+1</button>
      </div>
    )
  }
}

ReactDOM.render(<App />, document.getElementById('root'))
复制代码

El efecto es el siguiente:

3.gif

1.2 Sintaxis recomendada

Si el último this.setState() quiere realizar operaciones basadas en el resultado del primero this.setState(), ¿cómo debería implementarse? Métodos de la siguiente manera:

  • Recomendado: utilice la sintaxis setState((state,props) => {})
  • Estado del parámetro: indica el estado más reciente
  • Accesorios de parámetros: indica los últimos accesorios
// 导入ract
import React from 'react'
import ReactDOM from 'react-dom'

// App组件
class App extends React.Component {
  state = {
    count: 1
  }

  handleClick = () => {
    // 前面的setState()
    // 更新state
    // 注意:这种方法也是异步更新数据
    this.setState((state, props) => {
      return {
        count: state.count + 1// 1 + 1
      }
    })

    // 后面的setState()
    this.setState((state, props) => {
      console.log('第二次调用:', state)
      return {
        count: state.count + 1
      }
    })
    console.log('count:', this.state.count)// 1
  }

  render() {
    console.log('render')
    return (
      <div>
        <h1>计数器:{this.state.count}</h1>
        <button onClick={this.handleClick}>+1</button>
      </div>
    )
  }
}

ReactDOM.render(<App />, document.getElementById('root'))
复制代码

El efecto es el siguiente:

1.gif

1.3 El segundo parámetro de setState()

  • Escenario: hacer algo justo después de una actualización de estado (la página termina de volver a renderizarse)
  • Sintaxis: setSate(actualizador,[devolución de llamada])
this.setState(
    (state, props) => {},// 参数1
    () => {console.log('这个回调函数会在状态更新后立即执行')}// 参数2
)
复制代码

De hecho, el método setState() tiene un segundo parámetro, que es una función de devolución de llamada. Esta función de devolución de llamada se ejecutará inmediatamente después de la actualización de estado, por lo que si desea hacer algo después de la actualización de estado, puede acceder a esta función de devolución de llamada. .Ejecutar, su uso es el siguiente:

// 导入ract
import React from 'react'
import ReactDOM from 'react-dom'

// App组件
class App extends React.Component {
  state = {
    count: 1
  }

  handleClick = () => {
    this.setState(
      // 参数1
      (state, props) => {
        return { count: state.count + 1 }
      },

      // 参数2:在状态更新后且重新渲染后,立即执行
      () => {
        console.log('状态更新完成:', this.state.count)
        console.log(document.getElementById('title').innerText)
        document.title = '更新后的count为:' + this.state.count
      }
    )
    console.log("异步执行完以后的count:"+this.state.count)// 1
  }

  render() {
    return (
      <div>
        <h1 id='title'>计数器:{this.state.count}</h1>
        <button onClick={this.handleClick}>+1</button>
      </div>
    )
  }
}

ReactDOM.render(<App />, document.getElementById('root'))
复制代码

El efecto es el siguiente:

2.gif

Supongo que te gusta

Origin juejin.im/post/7133127251704922126
Recomendado
Clasificación