简体   繁体   English

这实际上是在改变国家吗?

[英]Is this actually mutating the state?

I've just put together a really basic bit of React functionality to show someone and my console tab is accusing me of mutating the state directly. 我刚刚整理了一个非常基本的React功能,以显示某人和我的控制台选项卡指责我直接改变状态。 I thought that as long as you're using this.setState() that you're basically fine. 我认为只要你使用this.setState()就可以了。

This little bit of code just spits out the first person from the person object stored in the state and then when you click the button it increments the age (this actually all works, incidentally). 这一点代码只是从存储在状态中的person对象中吐出第一个人,然后当你单击按钮时它会增加年龄(这实际上所有工作都是顺便进行的)。

Am I actually directly mutating the state by doing this? 我实际上通过这样做直接改变了状态吗? And if I am, what is the correct way of doing this? 如果我是,那么这样做的正确方法是什么?

import React, { Component } from 'react';
import './App.css';
import Person from './Person/Person';

class App extends Component {
  state = {
    persons: [
      { name: 'Max', age: 28 },
      { name: 'Stephanie', age: 26 },
      { name: 'Manu', age: 29 },
    ],
  }

  increaseAgeHandler = () => {
    this.setState({
      persons: [
        { name: 'Max', age: this.state.persons[0].age += 1 },
        { name: 'Stephanie', age: 26 },
        { name: 'Manu', age: 29 },
      ],
    });
  }

  render() {
    return (
      <div className="App">
        <h1>This is an app</h1>
        <button onClick={this.increaseAgeHandler}>Add to age</button>
        <Person name={this.state.persons[0].name} age={this.state.persons[0].age} />
      </div>
    );
  }
}

export default App;

As setState is asynchronous to increase the age by one it is advisable to pass the prevState as an argument to the setState callback function as below. 由于setState是异步的,将age的年龄​​增加1,因此建议将prevState作为参数传递给setState回调函数,如下所示。 Also there is no mutation of state if you add 1 to the previous state as below: 如果您将1添加到上一个状态,也没有状态突变,如下所示:

 increaseAgeHandler = () => {

    this.setState(prevState => {
      persons: [
        { name: 'Max', age: prevState.persons[0].age + 1 },
        { name: 'Stephanie', age: 26 },
        { name: 'Manu', age: 29 },
      ],
    });

  }

So doing: 这样做:

this.state.persons[0].age += 1

Is acutally a mutation you want to create a new pointer for the age variable so you're actually going to do: 实际上是你想要为年龄变量创建一个新指针的突变,所以你实际上要做的是:

this.state.persons[0].age + 1

This doesn't mutate previous value and adds a new pointer to your state, if you have any questions about this, just shoot! 这不会改变先前的值并添加一个指向你的状态的新指针,如果你对此有任何疑问,只需拍摄! Hope it's understandable. 希望这是可以理解的。

this.state.persons[0].age += 1

This changes the age directly because += is an assignment operator . 这会直接改变age ,因为+=赋值运算符 Instead, just add 1 to the age without assigning: 相反,只需在年龄中添加1而不指定:

this.state.persons[0].age + 1

When you call setState(), React merges the object you provide into the current state 当您调用setState()时,React会将您提供的对象合并到当前状态

constructor(props) {
    super(props);
    this.state = {
      persons: [
       { name: 'Max', age: 28 },
       { name: 'Stephanie', age: 26 },
       { name: 'Manu', age: 29 },
      ]
    };
  }

this.state it's only assinable on the constructor, then you can update them independently with separate setState() calls. this.state它只能在构造函数上使用,然后你可以使用单独的setState()调用独立更新它们。 Do Not Modify State Directly 不要直接修改状态

For example, this will not re-render a component: 例如,这不会重新渲染组件:

this.state.persons[0].age += 1

Instead, use setState(): 相反,使用setState():

increaseAgeHandler = () => {
    this.setState({
      persons: [
        { name: 'Max', age: this.state.persons[0].age += 1 },
        { name: 'Stephanie', age: 26 },
        { name: 'Manu', age: 29 },
      ],
    });
  }

More info about React lifecycle 有关React lifecycle的更多信息

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM