2014-11-27 2 views
17

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

Помощь!

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> 
    ) 
    } 
    }) 
+0

если вы вызываете setState самостоятельно, вы не должны ожидать, что this.state будет немедленно обновлен. –

ответ

5

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

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

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

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

6

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

спасибо вам большое :) – Giang

0

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

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