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

199
Vistas
Obtener el valor obsoleto de la variable de estado local después de la respuesta devuelta de la promesa

Tengo una aplicación de reacción con dos botones, que al hacer clic cargan el nombre de usuario del servidor. El comportamiento funciona si hago clic en los botones uno a la vez y espero la respuesta; sin embargo, si hago clic en ambos, la respuesta de la API para el segundo botón escribe un valor en el estado que está obsoleto debido a que el primer botón se atasca en el estado de carga. ¿Cómo puedo resolver esto para tener siempre los datos más recientes cuando se resuelve la promesa?

Demostración de espacio aislado de código: https://codesandbox.io/s/pensive-frost-qkm9xh?file=/src/App.js:0-1532

 import "./styles.css"; import LoadingButton from "@mui/lab/LoadingButton"; import { useRef, useState } from "react"; import { Typography } from "@mui/material"; const getUsersApi = (id) => { const users = { "12": "John", "47": "Paul", "55": "Alice" }; return new Promise((resolve) => { setTimeout((_) => { resolve(users[id]); }, 1000); }); }; export default function App() { const [users, setUsers] = useState({}); const availableUserIds = [12, 47]; const loadUser = (userId) => { // Mark button as loading const updatedUsers = { ...users }; updatedUsers[userId] = { id: userId, name: undefined, isLoading: true, isFailed: false }; setUsers(updatedUsers); // Call API getUsersApi(userId).then((userName) => { // Update state with user name const updatedUsers = { ...users }; updatedUsers[userId] = { ...updatedUsers[userId], name: userName, isLoading: false, isFailed: false }; setUsers(updatedUsers); }); }; return ( <div className="App"> {availableUserIds.map((userId) => users[userId]?.name ? ( <Typography variant="h3">{users[userId].name}</Typography> ) : ( <LoadingButton key={userId} loading={users[userId]?.isLoading} variant="outlined" onClick={() => loadUser(userId)} > Load User {userId} </LoadingButton> ) )} </div> ); }
about 4 years ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

El problema es que el setter de useState es asíncrono, por lo tanto, en su función de cargador, cuando define const updatedUsers = { ...users }; , el usuario no es necesario actualizar.

Afortunadamente, el setter de useState nos permite acceder al estado anterior. Si refactoriza su código de esta manera, debería funcionar:

 const loadUser = (userId) => { // Mark button as loading const updatedUsers = { ...users }; updatedUsers[userId] = { id: userId, name: undefined, isLoading: true, isFailed: false }; setUsers(updatedUsers); // Call API getUsersApi(userId).then((userName) => { // Update state with user name setUsers(prevUsers => { const updatedUsers = { ...prevUsers }; updatedUsers[userId] = { ...updatedUsers[userId], name: userName, isLoading: false, isFailed: false }; return updatedUsers }); }); };

Aquí un patio de juegos de React con una versión de trabajo simplificada.

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