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

202
Views
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 answers
Answer question

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 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!