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