2014-11-27 14 views
17

Ich probiere ReactJS aus, stoße aber in Schwierigkeiten, es in mein Formular einzufügen. Ich baue in ReactJS ein Auto-Suggest-Formular aus. In meinem onChangeQuery setze ich den Zustand und rufe dann zu einer AJAX-Funktion auf, um Vorschläge von meinem serverseitigen Code zu ergreifen; Allerdings habe ich bemerkt, dass die loadGroupsFromServer Funktion nicht den neuesten Stand bekommt ... Es ist ein Schlüsselstrich zu langsam. Ich weiß, setState ist nicht sofort, aber warum sollte ich dann setState für meine Formulare verwenden? Ist es besser, Refs zu verwenden? Lieber den Wert von e.target.value bekommen?ReactJS setState ist langsam

Hilfe!

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

Wenn Sie setState selbst aufrufen, sollten Sie nicht erwarten, dass dieser.Status sofort aktualisiert wird. –

Antwort

5

loadGroupsFromServer sollte ein Abfrageargument verwenden.

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

Sie sollten in der Regel versuchen, Zugriff auf Zustand zu reduzieren, da es Flexibilität mehr gibt Ihnen.

Je nach Fall können Sie für die Komponente warten, aktualisieren möchten, bevor eine Aktion durchführen:

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

Oder man könnte es so umschreiben, die sauberer ist meiner Meinung nach.

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 nimmt einen Rückruf, die Sie nur dann aufgerufen, um sicherzustellen, ermöglicht this.loadGroupsFromQuery() nach this.state aktualisiert wird.

3

Die Hauptursache für Ihr Ein-Zeichen-Aus-Problem war, dass Sie den Status gelesen haben, bevor er gesetzt wurde. setState ist schnell, aber nicht sofort und synchron. Die vorherigen Antworten bieten Ihnen einige Möglichkeiten zum Refactoring.

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

danke dir so viel :) – Giang

0

setState ist nicht langsam, aber es ist asynchron. Gemäß obiger Antwort funktioniert es synchron, wenn Ihr Status gesetzt ist.

Gemäß dem Best-Practice-Status sollte außerhalb der Render-Methode festgelegt werden.

Verwandte Themen