Как я могу отредактировать мой код без проблемы setState ()? - PullRequest
0 голосов
/ 07 июня 2019

У меня есть этот код в моем конструкторе:

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});

  }

Но даю мне это предупреждение:

Не изменять состояние напрямую. Используйте setState() не реагирует / не прямая мутация состояние

Что я могу сделать в этом случае? Может быть, как-то изменить строку с присваиванием event.target.value на setState()?

Ответы [ 6 ]

2 голосов
/ 07 июня 2019

Вы можете использовать map() для создания копии tests

edit(id, event) {
    const user = event.target.value;
    const tests = this.state.tests.map((x,i) =>  i === id ? {...x, user} : x);
    this.setState({tests});
}
1 голос
/ 07 июня 2019

Один из способов, которым я склонен, это сначала сделать копию массива, а затем изменить в нем элемент или изменить сам массив, а затем установить состояние

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

Возможно, вы захотитеглубокое клонирование массива в некоторых случаях, иногда нет.

0 голосов
/ 07 июня 2019

Прежде всего, когда вы пытаетесь установить новое состояние, используя данные из предыдущего состояния, вы должны использовать функцию обновления как функцию. 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
    };
  });
};
0 голосов
/ 07 июня 2019

Когда состояние не тяжелое, я использую следующие коды:

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)
  )
}
0 голосов
/ 07 июня 2019
edit(id, event) {
    var newNote = {...this.state.tests[id]}
    newNote.user = event.target.value
    this.setState({ tests: [...this.state.tests, newNote]})
}
0 голосов
/ 07 июня 2019

Вы правы, проблема в строке:

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 из вашего события, потому что небезопасно получать доступ к значениям события в асинхронных вызовах после обработки события.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...