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

242
Vistas
¿Cómo debo activar una nueva representación cuando el estado se actualiza dentro de useEffect()?

Estoy tratando de averiguar cómo debo estructurar mi código con ganchos React de manera que:

  1. Tengo una variable de estado que representa si mi aplicación está "cargando" resultados o no.
  2. Este estado de loading se establece en true cuando useEffect() se ejecuta para obtener datos para mostrar
  3. Al final de useEffect() configuro la loading como false
  4. En los componentes secundarios, este estado de loading se pasa como accesorio para cambiar varios componentes.

A continuación se muestra un modelo simplificado de mi código:

 const App = () => { const [state, stateDispatch] = useReducer(stateReducer,{loading: false}) useEffect(() => { stateDispatch({type:'loadingResults'}); loadResults(); stateDispatch({type:'finishedLoadingResults'}); }); return ( <ExampleComponent loading={state.loading} /> ); } const stateReducer = (prevState,action) => { switch(action.type) { case 'loadingResults': return {...prevState, loading:true}; case 'finishedLoadingResults': return {...prevState, loading: false}; default: throw new Error(); } }

El componente "secundario" de ejemplo se muestra a continuación:

 const SampleComponent = (props) => { const [buttonText, setButtonText] = useState('Load More'); useEffect(() => { if (props.loading) { setButtonText('Loading...') } else { setButtonText('Load More'); } },[props.loading]); return ( <div onClick={(event) => props.getBooks(event,false)} className="moreResults">{buttonText}</div> ) }

Con esta configuración actual, nunca veo que el componente secundario se vuelva a renderizar, aunque parece que if (props.loading) se evalúa correctamente. Por ejemplo, si coloco un console.log dentro de if check y else check, veo que ambos se imprimen cuando se cambia el estado de loading .

Alternativamente, si defino state.loading tiene una dependencia para la función useEffect() en el componente de la App , obtengo infinitas representaciones ya que estoy alternando el estado de loading dentro useEffect() .

¿Alguna idea de lo que me estoy perdiendo aquí?

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

0

No necesita useEffect o useState en su componente secundario. La propiedad está cambiando en el padre, por lo que es suficiente para volver a renderizar su componente.

 const SampleComponent = (props) => ( <div onClick={(event) => props.getBooks(event,false)} className="moreResults">{props.loading ? 'Loading...' : 'Load More'} </div> )
about 4 years ago · Juan Pablo Isaza Denunciar

0

Un componente decide volver a renderizar solo cuando cambia alguna de sus propiedades o estado.

Javascript ejecuta todo de forma síncrona debido a su naturaleza de subproceso único. Por lo tanto, la función de diferenciación de reacción para identificar si el componente debe volver a renderizarse o no ocurrirá en orden síncrono, que es después de que se complete la ejecución del gancho useEffect en este caso.

 useEffect(() => { stateDispatch({type:'loadingResults'}); // -> state update happened // -> but re-render won't happen, since useEffect metho execution is not complete yet loadResults(); stateDispatch({type:'finishedLoadingResults'}); });

Pero para entonces habrá terminado de cargar y restablecer el estado. Como no hay cambios, el componente no se volverá a renderizar.

Además, no puede establecer el estado fuera del gancho porque cualquier disparador de setState activará una nueva representación que establecerá nuevamente el estado y esto creará un bucle infinito.

Solución: Llame a setState para cargar dentro de una condición if fuera del bloque useEffect. Algo como esto.

 const App = () => { const [state, stateDispatch] = useReducer(stateReducer,{loading: false}) useEffect(() => { if(!state.loading) { loadResults(); stateDispatch({type:'finishedLoadingResults'}); } },[state.loading]); if(notResults) { stateDispatch({type:'loadingResults'}); } return ( <ExampleComponent loading={state.loading} /> ); }
about 4 years ago · Juan Pablo Isaza Denunciar

0

  • En primer lugar, useEffect en el componente de su aplicación no tiene una lista de dependencias, por lo que se ejecuta en cada procesamiento. Dado que establece el estado, esto provoca una nueva representación, después de lo cual se vuelve a llamar a su useEffect, y así sucesivamente. Así que obtiene un bucle infinito.

    Debe agregar una lista de dependencias a useEffect.

  • En segundo lugar, si su función loadData es una función asíncrona (lo que debería ser si está obteniendo datos), devolverá una promesa, por lo que puede enviar "finishedLoadingResults" cuando se resuelva la promesa.

    Esto da lo siguiente para su useEffect:

 useEffect(() => { stateDispatch({ type: "loadingResults" }); loadResults() .then(() => stateDispatch({ type: "finishedLoadingResults" })); }, []);
  • En tercer lugar, como ya señaló jmargolisvt, no necesita un useEffect adicional dentro de su componente secundario. Cuando el componente de su aplicación establece el estado de "carga", esto hará que el componente de la aplicación junto con el componente secundario se vuelvan a procesar, por lo que no es necesario usar la variable de estado buttonText.

Puede ver el código de trabajo en este Sandbox .

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