Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

221
Views
El estado del componente no se actualiza con el controlador select y onChange

Creé un componente que carga datos a través de xhr en el usuario selecciona un valor del elemento <select>.

 class SomeComponent extends Component { state = { data: [], currentCategory: 'all' } switchCategory = (ev) => { console.log('Selected category is ' + ev.target.value); this.setState({ currentCategory: ev.target.value }); this.loadData(); } loadData = async () => { let { currentCategory } = this.state; // Always print previous value!!! console.log(currentCategory); // Get data via XHR... } render() { return ( <div> <select value={currentCategory} onChange={this.switchCategory}> <option value="all">All</option> {categories.map( category => <option key={category._id} value={category.category}>{category.display}</option> )} </select> <table> // ... prints data with this.state.data </table> </div> ); } }

El código anterior es solo breve. El código es bastante simple, solo sincronizo un valor del elemento seleccionado con this.state.currentCategory, y detecto que está cambiando con el método switchCategory de la clase.

Pero el principal problema es que cuando accedo al estado del componente, siempre contiene un valor anterior, no un presente. Puede ver que actualizo la categoría actual en el valor de los cambios seleccionados.

 switchCategory = (ev) => { console.log('Selected category is ' + ev.target.value); this.setState({ currentCategory: ev.target.value }); this.loadData(); }

Entonces, en esta situación, this.state.currentCategory no debe tener "todos", como algo más "Apple", ¡pero aún contiene "todos", no un "Apple"!

 loadData = async () => { let { currentCategory } = this.state; // Always print previous value!!! I expected "Apple", but it has "all" console.log(currentCategory); // Get data via XHR... }

Entonces, finalmente, XHR ocurre con el valor anterior y me da datos incorrectos que no esperaba. Después de eso, al elegir otro valor de la selección (llamémoslo Banana), ¡tiene una manzana, no una banana!

Como sé, setState es un trabajo de "sincronización", por lo que llamar a this.switchCategory ocurrirá después de actualizar los estados, por lo que debe tener un valor actual, no uno anterior.

Pero cuando imprimo el estado del componente en la consola, no lo es.

Entonces, ¿qué me estoy perdiendo? ¿Por qué siempre obtengo datos antiguos, no presentes? Si estoy haciendo algo mal, ¿qué alternativas puedo hacer?

Cualquier consejo será muy apreciado. ¡Gracias!

over 4 years ago · Santiago Trujillo
1 answers
Answer question

0

El problema aquí es que setState es asíncrono (puede sincronizarse en ciertas situaciones). Es por eso que obtienes el valor anterior.

Hay dos soluciones posibles.

 // // 1. use value directly. // switchCategory = (ev) => { this.setState({ currentCategory: ev.target.value }); this.loadData(ev.target.value); } loadData = async (currentCategory) => { console.log(currentCategory); // Get data via XHR... } // // 2. use completition callback on `setState`. // switchCategory = (ev) => { this.setState({ currentCategory: ev.target.value }, () => { this.loadData(ev.target.value); }); } loadData = async () => { const { currentCategory } = this.state; console.log(currentCategory); // Get data via XHR... }

Artículo sobre setState síncrono en React [enlace]

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!