我如何编辑没有setState()问题的代码?

时间:2019-06-07 16:36:57

标签: javascript reactjs ecmascript-6

我的构造函数中有以下代码:

this.state = {
  tests: [
    {
      question: "1",
      answer: "2",
      user: ""
    },
    {
      question: "1",
      answer: "2",
      user: ""
    },

  ],

};

我具有编辑功能,可以在输入中读取事件值:

  edit(id, event) {
    this.state.tests[id].user = event.target.value;
    this.setState({tests:this.state.tests});

  }

但是es给我这个警告:

  

请勿直接更改状态。使用setState()   反应/无直接突变状态

在这种情况下我该怎么办?也许以某种方式将分配为event.target.value的行更改为setState()

6 个答案:

答案 0 :(得分:2)

您可以使用interface Model { side: 'left' | 'right'; } interface LeftModel extends Model { side: 'left'; } interface RightModel extends Model { side: 'right'; } function isLeft(value: Model): value is LeftModel { return value.side === 'left'; } function whatever(model: LeftModel | RightModel) { // This union makes the else branch work model.side // left or right if (isLeft(model)) { model.side; // left - model is also LeftModel at this point } else { model.side; // right - model is a RightModel } } 创建map()的副本

tests

答案 1 :(得分:1)

我倾向于的一种方法是先复制数组,然后更改其中的一项,或者更改数组本身,然后设置状态

var tests = this.state.tests.slice(0);
tests[id].user = event.target.value;
this.setState({tests:tests});

在某些情况下,您可能想深度克隆数组,有时不希望。

答案 2 :(得分:0)

您是对的,问题出在线路上

this.state.tests[id].user = event.target.value;

这就是您直接改变状态的地方。

您有一些选择。

您可以先“克隆”阵列,然后更新它:

const newTests = [...this.state.tests];
newTests[id].user = event.target.value;
this.setState({tests: newTests});

您也可以使用immutability-helper

const {value} = event.target;
this.setState(prevState => update(prevState, {[id]: {user: {$set: value}}}));

在此示例中,您需要从事件中提取value,因为在处理事件后访问异步调用中的事件值并不安全。

答案 3 :(得分:0)

edit(id, event) {
    var newNote = {...this.state.tests[id]}
    newNote.user = event.target.value
    this.setState({ tests: [...this.state.tests, newNote]})
}

答案 4 :(得分:0)

当状态不太沉重时,我使用以下代码:

edit (id, event) {
  const cp = JSON.parse(JSON.stringify(this.state.tests))
  cp[id].user = event.target.value
  this.setState({ tests: cp })
}

更新:我发现Immer完美解决了这个问题。

import produce from 'immer'

edit (id, event) {
  this.setState(
    produce(draft => draft.tests[id].user = event.target.value)
  )
}

答案 5 :(得分:0)

首先,当您尝试使用先前状态中的数据设置新状态时,必须使用更新程序 https://reactjs.org/docs/react-component.html#setstate

const edit = (id, event) => {
  this.setState((prevState) => {
    const tests = [...prevState.tests];
    tests[id] = {
      ...tests[id],
      user: event.target.value
    };
    return {
      ...prevState,
      tests
    };
  });
};