Подтвердить что ты не робот

ReactJS setState работает медленно

Я пытаюсь выполнить ReactJS, но мне сложно интегрировать его в мою форму. Я создаю форму для автоматического предложения в ReactJS. В моем onChangeQuery я устанавливаю состояние, а затем вызываю функцию AJAX, чтобы захватывать предложения из моего кода на стороне сервера; однако я заметил, что loadGroupsFromServer функция не получает последнее состояние... Это один ключевой ход слишком медленный. Я знаю, что setState не мгновен, но зачем мне использовать setState для моих форм? Лучше ли использовать ссылки? Лучше просто получить значение из e.target.value?

Help!

  var GroupForm = React.createClass({
    getInitialState: function() {
      return {query: "", groups: []}
    },
    componentDidMount: function () {
      this.loadGroupsFromServer();
    },
    loadGroupsFromServer: function () {
      $.ajax({
        type: "GET",
        url: this.props.url,
        data: {q: this.state.query},
        dataType: 'json',
        success: function (groups) {
          this.setState({groups: groups});
        }.bind(this),
        error: function (xhr, status, err) {
          console.error(this.props.url, status, err.toString());
        }.bind(this)
      });
    },
    onChangeQuery: function(e) {
      this.setState({query: e.target.value})
      this.loadGroupsFromServer();
    },
    render: function() {
      return (
        <div>
          <form class="form form-horizontal">
            <div class="col-lg-12">
              <input type="text" className="form-control" value={this.state.query} placeholder="Search for groups" onChange={this.onChangeQuery} />
            </div>
          </form>
          <GroupList groups={this.state.groups} />
        </div>
      )
    }
  })
4b9b3361

Ответ 1

setState выполняет обратный вызов, который позволяет гарантировать, что this.loadGroupsFromQuery() вызывается только после обновления this.state.

this.setState({...}, function() {
  this.loadGroupsFromQuery();
});

Ответ 2

loadGroupsFromServer должен принимать аргумент запроса.

componentDidMount: function () {
  this.loadGroupsFromServer(this.state.query);
},
loadGroupsFromServer: function (query) {
  $.ajax({
    /* ... */
    data: {q: query},
    /* ... */
  });
},
onChangeQuery: function(e) {
  this.setState({query: e.target.value})
  this.loadGroupsFromServer(e.target.value);
},

Обычно вы должны пытаться уменьшить доступ к состоянию, потому что это дает вам большую гибкость.

В зависимости от случая вам может потребоваться дождаться обновления компонента перед выполнением некоторых действий:

onChangeQuery: function(e) {
  this.setState({query: e.target.value}, function(){
      this.loadGroupsFromServer(this.state.query)
  }.bind(this));
},

Или вы можете переписать его вот так, что, по моему мнению, является более чистым.

onChangeQuery: function(e) {
  this.setState({query: e.target.value});
},
componentWillUpdate: function(nextProps, nextState){
  // optionally perform better heuristics, but this prevents them pressing space
  // from triggering an update
  if (nextState.query.trim() !== this.state.query.trim()) {
      this.loadGroupsFromServer(nextState.query);
  }
}

Ответ 3

setState Best Practice

ES5

this.setState(function(state){
   state.query= e.target.value;
}, function()=>{
   //after callback 
});

ES6

 this.setState(state => {
    state.query= e.target.value;
 }, ()=>{
   //after callback 
 });

Ответ 4

Основной причиной проблемы с одним символом было то, что вы читали состояние до его установки. setState работает быстро, но не мгновенно и синхронно. Предыдущие ответы предоставляют вам пару способов рефакторинга.

Ответ 5

setState не медленный, но он асинхронный. Таким образом, как и в предыдущем ответе, он будет работать синхронно, пока ваше состояние не будет установлено.

В соответствии с наилучшей практикой состояние должно быть установлено на стороне метода рендеринга.