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

138
Vistas
useCallback con objeto de estado actualizado - React.js

Tengo una llamada POST API que hago con un clic de botón. Tenemos un objeto de estado grande que se envía como body para una llamada POST . Este objeto de estado sigue actualizándose en función de las diferentes interacciones del usuario en la página.

 function QuotePreview(props) { const [quoteDetails, setQuoteDetails] = useState({}); const [loadingCreateQuote, setLoadingCreateQuote] = useState(false); useEffect(() => { if(apiResponse?.content?.quotePreview?.quoteDetails) { setQuoteDetails(apiResponse?.content?.quotePreview?.quoteDetails); } }, [apiResponse]); const onGridUpdate = (data) => { let subTotal = data.reduce((subTotal, {extendedPrice}) => subTotal + extendedPrice, 0); subTotal = Math.round((subTotal + Number.EPSILON) * 100) / 100 setQuoteDetails((previousQuoteDetails) => ({ ...previousQuoteDetails, subTotal: subTotal, Currency: currencySymbol, items: data, })); }; const createQuote = async () => { try { setLoadingCreateQuote(true); const result = await usPost(componentProp.quickQuoteEndpoint, quoteDetails); if (result.data?.content) { /** TODO: next steps with quoteId & confirmationId */ console.log(result.data.content); } return result.data; } catch( error ) { return error; } finally { setLoadingCreateQuote(false); } }; const handleQuickQuote = useCallback(createQuote, [quoteDetails, loadingCreateQuote]); const handleQuickQuoteWithoutDeals = (e) => { e.preventDefault(); // remove deal if present if (quoteDetails.hasOwnProperty("deal")) { delete quoteDetails.deal; } handleQuickQuote(); } const generalInfoChange = (generalInformation) =>{ setQuoteDetails((previousQuoteDetails) => ( { ...previousQuoteDetails, tier: generalInformation.tier, } )); } const endUserInfoChange = (endUserlInformation) =>{ setQuoteDetails((previousQuoteDetails) => ( { ...previousQuoteDetails, endUser: endUserlInformation, } )); } return ( <div className="cmp-quote-preview"> {/* child components [handleQuickQuote will be passed down] */} </div> ); }

cuando se llama a la función handleQuickQuoteWithoutDeals , elimino una clave del objeto. Pero me gustaría llamar inmediatamente a la API con el objeto actualizado. Estoy eliminando la clave de trato directamente aquí, pero si lo hago de forma inmutable, la siguiente llamada a la API no está considerando el objeto actualizado sino el anterior.

La única forma que encontré para solucionar esto fue introducir un nuevo estado y actualizarlo al hacer clic y luego hacer uso del gancho useEffect para rastrear este estado y hacer la llamada a la API cuando cambia. Con este enfoque, funciona de una manera extraña en la que sigue llamando a la API en la carga inicial y otros comportamientos extraños.

¿Hay una manera más limpia de hacer esto?

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

0

No está claro cómo los niños llamarían a la devolución de llamada handleQuickQuote , pero si necesita cerrar en el alcance de la devolución de llamada una "copia" de los detalles de quoteDetails , entonces sugiero el siguiente pequeño refactor para permitir que este componente principal use la función createQuote sin procesar mientras los niños reciben una devolución de llamada memorizada con los detalles de la quoteDetails actual adjuntos.

Consumir quoteDetails como argumento:

 const createQuote = async (quoteDetails) => { try { setLoadingCreateQuote(true); const result = await usPost(componentProp.quickQuoteEndpoint, quoteDetails); if (result.data?.content) { /** TODO: next steps with quoteId & confirmationId */ console.log(result.data.content); } return result.data; } catch( error ) { return error; } finally { setLoadingCreateQuote(false); } };

Memoice una devolución de llamada "anónima" que pasa en el valor de quoteDetails :

 const handleQuickQuote = useCallback( () => createQuote(quoteDetails), [quoteDetails] );

Cree una copia superficial de quoteDetails , elimine la propiedad y llame a createQuote :

 const handleQuickQuoteWithoutDeals = (e) => { e.preventDefault(); const quoteDetailsCopy = { ...quoteDetails }; // remove deal if present if (quoteDetailsCopy.hasOwnProperty("deal")) { delete quoteDetailsCopy.deal; } createQuote(quoteDetailsCopy); }
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