Понимание состояния ввода в реакции - PullRequest
0 голосов
/ 28 апреля 2020

У меня есть метод submitMessage, который должен объединить текущее сообщение, которое было сохранено в моем состоянии ввода, а затем очистить его:

submitMessage() {
  this.setState({
    input: '',
    messages : [...this.state.messages, this.state.input]
  });
}

Метод работает, как предполагалось, и все приложение Кроме того, я не понимаю, почему ввод может быть очищен до объединения, ввод и this.state.input не в том же месте в памяти?

Вот мой полный код:

class DisplayMessages extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      input: '',
      messages: []
    }    
  }
  handleChange(event) {
    this.setState({
      input: event.target.value,
      messages: this.state.messages
      })
  }
  submitMessage() {
    this.setState({
      input: '',
    messages : [...this.state.messages, this.state.input]
    })
  }
  render() {
    return (
      <div>
        <h2>Type in a new Message:</h2>
        <input onChange={this.handleChange.bind(this)} value={this.state.input} />
        <button onClick={this.submitMessage.bind(this)}>Submit</button>
        <ul>{this.state.messages.map((item) => {
            return <li key={item + 1}>{item}</li>
          })}
        </ul>
      </div>
    );
  }
};

1 Ответ

1 голос
/ 28 апреля 2020

Почему <input /> и this.state.input не находятся в одном и том же месте в памяти?

input является элементом html DOM, а другой, this.state.input это javascript объект, это две совершенно разные вещи. Единственное, что связано с этими двумя понятиями, - это синтаксис JSX и структура реагирования.

Почему ввод может быть очищен перед объединением сообщений?

В реагировании обрабатываются состояния и параметры как неизменяемые объекты, так и реагируют состояния работ между циклами рендеринга. Все обновления состояния в любом одном цикле ставятся в очередь и обрабатываются пакетно для следующего цикла рендеринга. Установка this.state.input для пустой строки и добавление ее в массив this.state.messages ставятся в очередь для обработки для следующего визуализированного представления.

Ниже приведены все эквивалентны с точки зрения следующего вычисленного состояния:

this.setState({
  input: '',
  messages: [...this.state.messages, this.state.input],
});

и

this.setState({
  messages: [...this.state.messages, this.state.input],
  input: '',
});

и

this.setState({ input: '' });
this.setState({
  messages: [...this.state.messages, this.state.input],
});

и даже

this.setState({ input: '' });
this.setState({
  messages: [...this.state.messages, this.state.input],
});
this.setState({
  messages: [...this.state.messages, this.state.input],
});

последний из них может вас удивить ( что!? ), но помните, что состояние состояния является неизменным и обрабатывается пакетно, поэтому в случае обновления messages, this.state.messages и this.state.input имеют одинаковые значения в обоих вызовах, и, таким образом, последний из них вызывает состояние. Кстати, (и за пределами этого вопроса) обновления функционального состояния помогают решить проблему с помощью последнего примера.

...