Code Monkey home page Code Monkey logo

me's People

Contributors

abcliuyong2008 avatar

Watchers

 avatar  avatar

me's Issues

React的this.setState的异步问题

问题描述

在某个方法中,在调用 setState 之后,希望能立刻拿到新的state,结果一直是老的值。

先说原因

setState是异步执行的。下面是一段官方描述:

incrementCount() {
  // 注意:这样 *不会* 像预期的那样工作。
  this.setState({count: this.state.count + 1});
}

handleSomething() {
  // 假设 `this.state.count` 从 0 开始。
  this.incrementCount();
  this.incrementCount();
  this.incrementCount();
  // 当 React 重新渲染该组件时,`this.state.count` 会变为 1,而不是你期望的 3。

  // 这是因为上面的 `incrementCount()` 函数是从 `this.state.count` 中读取数据的,
  // 但是 React 不会更新 `this.state.count`,直到该组件被重新渲染。
  // 所以最终 `incrementCount()` 每次读取 `this.state.count` 的值都是 0,并将它设为 1。

  // 问题的修复参见下面的说明。
}
我应该如何更新那些依赖于当前的 state 的 state 呢?
给 setState 传递一个函数,而不是一个对象,就可以确保每次的调用都是使用最新版的 state(见下面的说明)。

给 setState 传递一个对象与传递一个函数的区别是什么?
传递一个函数可以让你在函数内访问到当前的 state 的值。因为 setState 的调用是分批的,所以你可以链式地进行更新,并确保它们是一个建立在另一个之上的,这样才不会发生冲突:

setState 什么时候是异步的?
目前,在事件处理函数内部的 setState 是异步的。

例如,如果 Parent 和 Child 在同一个 click 事件中都调用了 setState ,这样就可以确保 Child 不会被重新渲染两次。取而代之的是,React 会将该 state “冲洗” 到浏览器事件结束的时候,再统一地进行更新。这种机制可以在大型应用中得到很好的性能提升。

这只是一个实现的细节,所以请不要直接依赖于这种机制。在以后的版本当中,React 会在更多的情况下静默地使用 state 的批更新机制。

为什么 React 不同步地更新 this.state?
如前面章节解释的那样,在开始重新渲染之前,React 会有意地进行“等待”,直到所有在组件的事件处理函数内调用的 setState() 完成之后。这样可以通过避免不必要的重新渲染来提升性能。

但是,你可能还是会想,为什么 React 不能立即更新 this.state,而不对组件进行重新渲染呢。

主要有两个原因:

这样会破坏掉 props 和 state 之间的一致性,造成一些难以 debug 的问题。
这样会让一些我们正在实现的新功能变得无法实现。

解决办法

1.设计一个全局变量。(感觉跟react state的**有冲突,本人不推荐使用)

2.直接使用this.state.count = this.state.count + 1 来修改(不会重新渲染组件)

3.给 setState传递一个函数,而不是一个对象(推荐使用)

this.setState((state) => {
      const newCount = state.count + 1
      console.log(newCount)
      return { count: newCount }
    })

4.React控制之外的事件中调用setState是同步更新的。比如原生js绑定的事件,setTimeout/setInterval等

setTimeout(()=>{
this.setState({count: this.state.count + 1});
console.log(this.state.count)
});

5.给setState给第二个参数传递一个回调函数(能拿到新值,但是重复调用最终结果只会+1)

this.setState({ count: this.state.count + 1 }, () => {
      console.log(this.state.count)
    })

参考:https://zh-hans.reactjs.org/docs/faq-state.html#what-does-setstate-do

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.