【问题标题】:ReactJS - setState() not reflecting change immediatelyReactJS - setState() 没有立即反映变化
【发布时间】:2020-11-25 10:31:40
【问题描述】:

我的代码如下:

import React, { Component } from 'react';

class Counter extends Component {

    constructor() {
        super();
        this.state = {
            counter : 0
        }
    }


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


    render() {
        const { counter} = this.state;
        return (
            <div>
                <h1> {counter} </h1>
                <button onClick={() => this.increment()}>Click Me</button>
            </div>
        );
    }
}

export default Counter;

我有一个简单的 h1 和一个按钮。程序的行为应该是,当我单击按钮时,计数器的值应该增加 1(在网页和控制台上,因为我也在控制台中打印计数器的值)。问题是,当我单击按钮时,我的网页上的值从 0 变为 1,但在我的控制台中,我仍然看到计数器的值为 0(而不是 1),当我第二次单击按钮时,值从在我的网页上从 1 变为 2,但在我的控制台中,值从 0 变为 1(而不是 2)。谁能告诉我这是怎么回事?

【问题讨论】:

  • 那么我应该怎么做才能得到我想要的输出呢?
  • 你能告诉我怎么做吗?
  • 不使用 prevCounter 有没有其他方法?
  • 我的第一条评论有误,以下是更新您的情况的正确方法:this.setState(prevState =&gt; ({ counter: prevState.counter + 1 }), () =&gt; console.log(counter));
  • 关于setState 的异步特性,两个答案都是正确的。但是在您的情况下,即使它是完全同步的,您也会因为初始解构分配而简单地记录 old 值。由于state.counter 是一个标量值,您实际上已将该值复制到counter 变量中。之后对state.counter 的任何更改都不会反映。演示:jsfiddle.net/vf1kwnuc

标签: javascript reactjs setstate


【解决方案1】:

this.setState() 是一个异步函数,因此在移动到下一行时会在后台发生。 要在 setState() 之后运行代码,您需要一个回调 - 因此在您的示例中它将是:

this.setState(prevState => ({ counter: prevState.counter + 1 }), () => console.log(counter)); // the console.log() will only run after the setState is finished!

它很容易忘记它的异步,因为它经常发生得太快,你可以在之后立即console.log() 并且状态已经改变!

【讨论】:

    【解决方案2】:

    setState 操作是异步的,为了提高性能而进行批处理。这在documentation of setState 中有解释。

    setState() 不会立即改变 this.state 而是创建一个挂起的状态转换。在调用此方法后访问 this.state 可能会返回现有值。无法保证 setState 调用的同步操作,并且调用可能会被批处理以提高性能。

    您可以使用 setState 回调来查找即时更改,也可以使用 componentDidUpdate

    this.setState({ counter : counter+1 }, newState => {
       console.log(newState.counter)
    });
    
    

    componentDidUpdate(prevProps, prevState) {
      console.log(this.state) // New State
      console.log(prevState) // Previous State
      if (this.state.counter !== prevState.counter) {
        // counter changed
      }
    }
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-10-10
      • 1970-01-01
      • 1970-01-01
      • 2021-09-10
      相关资源
      最近更新 更多