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

313
Vistas
La 'declaración if else' no funciona correctamente al importar datos como accesorios en React

if else declaración dentro useEffect no funciona como se esperaba. else se ejecuta antes de que el código dentro de if se ejecute por completo. He comentado lo que espero en el código. someData prop son los datos obtenidos del servidor utilizando la fetch API de obtención en el componente principal.

 import { useState, useEffect } from "react"; const App = ({ someData }) => { const [text, setText] = useState(0) const [lastNumber, setLastNumber] = useState(0) useEffect(() => { if (!someData) { (async () => { const res = await fetch(`https://xxx-xxx......`); const myJson = await res.json(); const _lastNumber = myJson.number // 1000 setLastNumber(_lastNumber) console.log(lastNumber) // 1000, appear in the console second })(); } else { console.log(lastNumber) // 0, appear in the console first setText( lastNumber - someData.number // 0 - 100 (I expect "1000 - 100".) ); } }, [someData, lastNumber]); if (!someData) { return ( <div> <h1>Loading</h1> </div> ) } else { return ( <div> <h1>{text /* -100 (I expect "900".) */}</h1> </div> ); } }; export default App;

Si escribo código como este usando algunos trucos, toma mucho tiempo cargar pero funciona como quiero.

 import { useState, useEffect } from "react"; const App = ({ someData }) => { const [text, setText] = useState(0) const [lastNumber, setLastNumber] = useState(0) useEffect(() => { if (!someData) { (async () => { const res = await fetch(`https://xxx-xxx......`); const myJson = await res.json(); const _lastNumber = myJson.number // 1000 setLastNumber(_lastNumber) console.log(lastNumber) })(); } else { if (lastNumber !== 0) { console.log(lastNumber) setText( lastNumber - someData.number ); } } }, [someData, lastNumber]); if (!someData) { return ( <div> <h1>Loading</h1> </div> ) } else { return ( <div> <h1>{text /* 900 */}</h1> </div> ); } }; export default App;

Pero no sé por qué funciona de la manera que quiero y si es una buena manera de hacerlo. Por favor, hágamelo saber la mejor manera.

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

0

Debe mover el efecto en la función async dedicada, para await parte de la ejecución. En su solución actual, su efecto es sincrónico y el IIFE que declaró se ejecutará sincrónicamente, por lo que puede causar un comportamiento inesperado del efecto.

Vuelva a escribir esto (para esperar la ejecución del código):

 const doSomething = async () => { if (!someData) { const res = await fetch(`https://xxx-xxx......`); // NOW YOU CODE WILL WAIT const myJson = await res.json(); const _lastNumber = myJson.number; // 1000 setLastNumber(_lastNumber); console.log(lastNumber); // YOU CAN NOT EXPECT TO READ NEW VALUE IMMEDIATELY, THIS WILL LOG OLD VALUE FOR lastNumber } else { console.log(lastNumber); // 0, appear in the console first setText( lastNumber - someData.number // 0 - 100 (I expect "1000 - 100".) ); } }; useEffect(() => { doSomething(); }, [someData, lastNumber]);

Además, en la parte console.log(lastNumber) no puede esperar registrar el valor más reciente, uno que se configuró en línea antes, porque la actualización de estado es asíncrona y se accede al estado desde el cierre, lo que significa que accederá al nuevo valor de lastNumber pero solo después de volver a procesar .

about 4 years ago · Juan Pablo Isaza Denunciar

0

¡Sí! Funciones asíncronas... )) Lea este artículo para obtener explicaciones.

El problema aquí es que se supone que el primer argumento de useEffect es una función que no devuelve nada (indefinido) o una función (para limpiar los efectos secundarios). ¡Pero una función asíncrona devuelve una Promesa, que no se puede llamar como una función! Simplemente no es lo que espera el gancho useEffect para su primer argumento.

 enum LoadingStatusEnum { INACTIVE = -1, ACTIVE = 1, ERROR = 0, } export default function Example({someData}): JSX.Element { const [text, setText] = useState(0); const [lastNumber, setLastNumber] = useState(0); const [loadingStatus, setLoadingStatus] = useState<LoadingStatusEnum>(LoadingStatusEnum.INACTIVE); useEffect(() => { const fetchData = async () => { setLoadingStatus(LoadingStatusEnum.ACTIVE); const response = await fetch('API action here'); const json = await response.json(); setLastNumber(json.number); }; if (!someData && loadingStatus !== LoadingStatusEnum.ACTIVE) { fetchData() .then(() => { setLoadingStatus(LoadingStatusEnum.INACTIVE); }) .catch(() => { setLoadingStatus(LoadingStatusEnum.ERROR); }); } else { setText(lastNumber - someData.number); } }, [someData, lastNumber]); const renderTitle = () => { let title = String(text); if (loadingStatus === LoadingStatusEnum.ACTIVE) { title = 'Loading'; } if (loadingStatus === LoadingStatusEnum.ERROR) { title = 'Error'; } return title; }; return ( <div> <h1> {renderTitle()} </h1> </div> ); }
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