首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >同时在状态上设置多个(相互依存)值

同时在状态上设置多个(相互依存)值
EN

Stack Overflow用户
提问于 2019-09-17 14:39:42
回答 2查看 211关注 0票数 2

想象一下这段代码:

代码语言:javascript
运行
复制
class App extends React.Component {
  state = {
    name: "george",
    counter: 1
  };

  onClick() {
    this.setState({
      counter: 123,
      name: this.state.name + this.state.counter
    });


  }

  render() {
    return (
      <div
        className="App"
        onClick={() => {
          this.onClick();
        }}
      >
        <h1>Hello CodeSandbox</h1>
        <h2>{this.state.name}</h2>
        <h2>{this.state.counter}</h2>
      </div>
    );
  }
}

如果我单击div,输出是:

代码语言:javascript
运行
复制
george1
123

您可以看到,state.name的值是george1包含了的值,该值在 onClick 称为时是当前的。不过,state.counter值本身具有新的值。

这是怎么解释的?因为如果我这样做:

代码语言:javascript
运行
复制
 onClick() {
    this.setState({
      counter: 123
    });

    setTimeout(() => {
      this.setState({
        name: this.state.name + this.state.counter
      });
    }, 1000);
  }

现在输出是

代码语言:javascript
运行
复制
george123
123

它基本上是相同的代码,但具有不同的时间。那么,是什么解释了这种行为呢?为什么在第一种情况下,它具有嵌入在this.state.counter this.state.name**?**中的(单击时)的当前值,而在第二种情况下则没有?

演示

我知道,如果我想将counter的旧值嵌入到this.state.name中,并更新this.state.counter,我也可以这样做:

代码语言:javascript
运行
复制
 onClick() {
    this.setState({ // even safer to use functional setState here
        name: this.state.name + this.state.counter
    }, ()=>{
       this.setState({ // and here
         counter:123
       })
    });


  }

它比No1方法安全吗(结果相同)?

EN

回答 2

Stack Overflow用户

发布于 2019-09-17 14:48:39

在这两个示例中都使用了counter的值。区别在于当counter的值发生变化时。在本例中:

代码语言:javascript
运行
复制
onClick() {
    this.setState({
      counter: 123,
      name: this.state.name + this.state.counter
    });

名称是george1,因为this.state.counter仍然被设置为1 (它还没有更新)。

在本例中:

代码语言:javascript
运行
复制
this.setState({
      counter: 123
    });

    setTimeout(() => {
      this.setState({
        name: this.state.name + this.state.counter
      });
    }, 1000);

您首先要更新counter的值,所以在超时this.state.counter引用新值之后,name值将是george123

另外,如果需要在setState函数中引用状态,则应该使用回调,以保证状态的正确值。

票数 0
EN

Stack Overflow用户

发布于 2019-09-17 15:11:10

正如您在注释和答案中所看到的,使用setTimeout并不那么可靠。大多数时候,你可以改变你的逻辑,解决你的问题。我不太确定您的应用程序中的计数器将如何变化,但是下面是一个如何管理它的示例。使用setState回调,您可以同时达到相同的countername值。

代码语言:javascript
运行
复制
class App extends React.Component {
  state = {
    name: "george",
    counter: 1
  };

  onClick() {
    this.setState(prevState => ({
      counter: prevState.counter + 1,
      name: `${prevState.name}${prevState.counter + 1}`
    }));
  }

  render() {
    return (
      <div onClick={() => this.onClick()}>
        <h2>{this.state.name}</h2>
        <h2>{this.state.counter}</h2>
      </div>
    );
  }
}

ReactDOM.render(<App />, document.getElementById("root"));
代码语言:javascript
运行
复制
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root" />

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57976686

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档