Saltar al contenido

React Hooks: useEffect() se llama dos veces incluso si está vacío array se usa como argumento

Hola, hemos encontrado la respuesta a lo que necesitas, continúa leyendo y la hallarás aquí.

Solución:

Coloque el archivo console.log dentro de useEffect

Probablemente tenga otros efectos secundarios que hagan que el componente se vuelva a procesar, pero el useEffect solo se llamará una vez. Puede ver esto con seguridad con el siguiente código.

useEffect(()=>
      /*
      Query logic
      */
      console.log('i fire once');
,[]);

Si el registro “disparo una vez” se activa más de una vez, significa que su problema es una de 2 cosas.

Este componente aparece más de una vez en su página

Este debería ser obvio, su componente está en la página un par de veces y cada uno montará y ejecutará el useEffect

Algo más arriba en el árbol se está desmontando y volviendo a montar

El componente se ve obligado a desmontarse y volver a montarse en su representación inicial. Esto podría ser algo así como un “key” el cambio ocurre más arriba en el árbol. Debe subir cada nivel con este useEffect hasta que se represente solo una vez. Entonces debería poder encontrar la causa o el remontaje.

No estoy seguro de por qué no pondrá el resultado en el estado, aquí hay un ejemplo que llama al efecto una vez, por lo que debe haber hecho algo en el código no publicado que hace que se reproduzca nuevamente:

const App = () => 
  const [isLoading, setLoad] = React.useState(true)
  const [data, setData] = React.useState([])
  React.useEffect(() => 
    console.log('in effect')
    fetch('https://jsonplaceholder.typicode.com/todos')
      .then(result => result.json())
      .then(data => 
        setLoad(false)//causes re render
        setData(data)//causes re render
      )
  ,[])
  //first log in console, effect happens after render
  console.log('rendering:', data.length, isLoading)
  return 
JSON.stringify(data, undefined, 2)

//render app
ReactDOM.render(, document.getElementById('root'))



Para evitar el procesamiento adicional, puede combinar datos y carga en un solo estado:

const useIsMounted = () => 
  const isMounted = React.useRef(false);
  React.useEffect(() => 
    isMounted.current = true;
    return () => isMounted.current = false;
  , []);
  return isMounted;
;


const App = () => 
  const [result, setResult] = React.useState(
    loading: true,
    data: []
  )
  const isMounted = useIsMounted();
  React.useEffect(() => 
    console.log('in effect')
    fetch('https://jsonplaceholder.typicode.com/todos')
      .then(result => result.json())
      .then(data => 
        //before setting state in async function you should
        //  alsways check if the component is still mounted or
        //  react will spit out warnings
        isMounted.current && setResult( loading: false, data )
      )
  ,[isMounted])
  console.log(
    'rendering:',
    result.data.length,
    result.loading
  )
  return (
    
JSON.stringify(result.data, undefined, 2)

)

//render app
ReactDOM.render(, document.getElementById('root'))



Reseñas y puntuaciones de la guía

Si te ha sido provechoso este post, sería de mucha ayuda si lo compartieras con el resto juniors de esta manera contrubuyes a extender esta información.

¡Haz clic para puntuar esta entrada!
(Votos: 2 Promedio: 4.5)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *