更改setState中的状态或对其进行克隆会更好吗?

时间:2019-04-29 16:05:18

标签: reactjs

这是我的状态:

state = {
    people: [
      { name: "aaa", age: 35 },
      { name: "bbb", age: 36 },
      { name: "ccc", age: 32 }
    ]
  };

,我想将第二个名称更改为xxx。我使用Lodash,这是我的工作,而且有效:

const newPeople = _.cloneDeep(this.statae.people);
newPeople[1].name = "xxx";
this.setState({people: newPeople});

但是我觉得我太夸张了,太挑剔了!

因为当我删除深层克隆并仅在setState中使用了突变状态后,它再次起作用:

 const newPeople = this.state.people;
    newPeople[1].name = "xxx";
    this.setState({people: newPeople});

但我的怀疑来自这样一个事实,即我听说不进行突变而是使用真正的克隆一直是一个好习惯。

现在

第一个问题是,您是否同意我在这里的克隆书?或者不,您认为我的克隆书太多了?

第二个问题是,如果您要我使用状态本身而不是克隆,在这种情况下是否需要使用我们通过函数this.setState((currentState,props)=>())的setState格式?

2 个答案:

答案 0 :(得分:0)

  

您是否同意我在这里的克隆书?或者不,您认为我的克隆书太多了?

您必须制作一个深层副本以便渲染该组件,但是这里没有理由使用lodash

this.state.people[1].name = "xxx";
this.setState({ people: ...this.state.people });

// More readable
const newPeople = this.state.people                   // Shallow copy
newPeople[1].name = "xxx";
this.setState({ people: ...newPeople });

进行浅拷贝时,它将不起作用:

const newPeople = this.state.people;  // Shallow-copy
newPeople[1].name = "xxx";
this.setState({people: newPeople});   // Won't Render because newPeople === this.state.people

您可以看到我制作的一个示例here

  

如果您要我使用状态本身而不是克隆,在这种情况下是否需要使用我们通过函数this.setState((currentState,props)=>())的setState格式?< / p>

如果您在prevState上使用新状态 请记住,状态可以是异步,React可以将多个setState()调用批处理为单个更新以提高性能。

this.propsthis.state可能是异步更新的,您不应依靠它们的值来计算下一个状态。

const newPeople = this.state.people
newPeople[1].name = "xxx" + props.newName;
this.setState({ people: ...newPeople })                // Bad on high traffic

this.setState((prevState, prevProps) => {              // Good
const newPeople = prevState.people;
newPeople[1].name = "xxx" + prevProps.newName;
return { people: ...newPeople }
}

您的情况下,只需使用this.setState({ people: ...newPeople })

答案 1 :(得分:-1)

  onUpdatePerson = (index, updatedKeys /*e.g. {name: 'xxx'} */) => {
    this.setState(state => {
      const updatedStatePeople = state.people.map((person, j) => {
        if (j === index) {
          return {
            ...person,
            ...updatedKeys
          };
        } else {
          return person;
        }
      });

      return {
        ...state,
        people: updatedStatePeople,
      };
    });
  };