Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

144
Vistas
Ignorar el resultado de devolución de llamada anterior si el estado ha cambiado mientras tanto

Tengo una página que muestra una lista de países proporcionada por una biblioteca externa. Cuando hago clic en un país, me muestra todas las ciudades en él.
Cada objeto de país tiene un método para obtener la lista de ciudades que contiene, proporcionado por la biblioteca.
Tengo un CountryComponent como este

 import { City, Country } from "an-external-library"; export const CountryComponent: FC<Props> = ({ country: Country }) => { const [cities, setCities] = useState<City[]>([]); useEffect(() => { country .getCities() .then(setCities) .catch(console.error); }, [country]); // ... }

Quiero obtener cities cada vez que se monta el componente y también si cambia el country .
El problema es que si sigo cambiando el país rápidamente, llamará a getCities() cada vez que haga clic en un país de la lista. Como no hay forma de saber en qué orden llegarán las respuestas a esas llamadas, al final las cities serán la respuesta que llegó en último lugar, sea la que sea.
Esto significa que puedo terminar con el país: Francia; ciudades: Nueva York, Los Ángeles, etc...


Soluciones que he probado

  • Desmontar CountryComponent y volver a montar si cambia country .

En el componente principal, tengo

 const handleChangeCountry = (c: Country) => { setCountry(undefined); setTimeout(() => setCountry(c), 10); } render ( <> <CountryList onCountryClick={handleChangeCountry}/> {country ? <CountryComponent country={country}/> : <Spinner /> }) </> )

Esta es una solución tan fea que solo escribir esto me da escalofríos.
Pero funcionó. Solo que no pude hacer que la interfaz de usuario se viera limpia cuando CountryComponent desapareció durante 10 ms y volvió a aparecer; y quiero una mejor solución.


Soluciones que no he probado

Como sugirió debouncing , la eliminación de rebotes podría ser una solución.
Mientras buscaba soluciones antes de publicar, encontré esta respuesta , pero no la probé porque creo que haría que la lista de ciudades tardara un poco en responder a los clics en los países, y eso tampoco es lo ideal.


Idealmente, me gustaría ignorar todas las devoluciones de llamada de getCities() excepto la última, pero no sé cómo lograría esto.

about 4 years ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

Este es un problema típico: obtiene respuestas asincrónicas desordenadas, lo que potencialmente sobrescribe el estado más reciente (y el único relevante).

Una solución muy fácil es usar el gancho useAsync react-use , que incluye varios mecanismos útiles para este problema típico, el interesante aquí es que descarta las respuestas de todas las solicitudes anteriores, manteniendo solo la respuesta a la solicitud más reciente.

Gancho de reacción que resuelve una función asíncrona o una función que devuelve una promesa;

 import { useAsync } from "react-use"; const CountryComponent = ({ country: Country }) => { // With react-use's useAsync, // no need for separate state and useEffect const cities = useAsync( () => country.getCities(), [country] ).value; // returned object { loading: boolean, value: T, error } // ... }
about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda