react reactjs

reactjs - react setstate delay



ReactJS setState es lento (5)

Estoy probando ReactJS, pero tengo dificultades para incorporarlo a mi formulario. Estoy creando un formulario de sugerencias automáticas en ReactJS. En mi onChangeQuery , estoy configurando el estado y luego llamando a una función AJAX para obtener sugerencias de mi código del lado del servidor; sin embargo, he notado que la función loadGroupsFromServer no está obteniendo el estado más reciente ... Es un loadGroupsFromServer tecla demasiado lento. Sé que setState no es instantáneo, pero entonces ¿por qué usaría setState para mis formularios? ¿Es mejor usar refs? ¿Mejor solo obtener el valor de e.target.value ?

¡Ayuda!

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


La causa raíz de su problema de desactivación de un carácter fue que estaba leyendo el estado antes de configurarlo. setState es rápido, pero no es instantáneo y sincrónico. Las respuestas anteriores le proporcionan un par de maneras de refactorizar.


loadGroupsFromServer debe tomar un argumento de consulta.

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

Por lo general, debe intentar reducir el acceso al estado porque le brinda más flexibilidad.

Dependiendo del caso, es posible que desee esperar a que el componente se actualice antes de realizar alguna acción:

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

O podrías reescribirlo así, lo cual es más limpio en mi opinión.

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


setState no es lento, pero es asíncrono. Por lo tanto, según la respuesta anterior, funcionará de forma síncrona, independientemente de su estado.

Según el estado de la mejor práctica, debe establecerse fuera del método de renderizado.


setState recibe una devolución de llamada que le permite garantizar que se this.loadGroupsFromQuery() a this.loadGroupsFromQuery() solo después de que se actualice this.state .

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


Mejores Prácticas de SetState

ES5

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

ES6

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