Crea una cuenta o inicia sesión

¡Continúa aprendiendo sin ningún costo! Únete y comienza a potenciar tu carrera

Efectos con useEffect

4/19
Recursos

Aportes 18

Preguntas 5

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

o inicia sesión.

Yo si quiero un curso de optimización de render en react 🙋🏾‍♀️

React.useEffect es un método con 2 parámetros:

  1. El primero, siempre se usa y es una función a ejecutar.

  2. El segundo, opcional e importante, nos indica cuando se va a ejecutar nuestro primer parámetro. Los posibles valores de este parámetro son:

    1. Ningun valor:
      esta función se ejecutará cada vez que nuestro componente haga render (es decir, cada vez que haya cambios en cualquiera de nuestros estados).

    2. Arreglo vacio:
      nuestro efecto solo se ejecuta una vez, cuando recién hacemos el primer render de nuestro componente.

    3. Arreglo no vacio:
      O también podemos enviar un array con distintos elementos para decirle a nuestro efecto que no solo ejecute en el primer render, sino también cuando haya cambios en esos elementos del array.

El React.useEffect recibe dos parámetros: el primer argumento es una función y el segundo argumento nos dice cuando se va a ejecutar el primer argumento.

React.useEffect(() => {}, []);

Valores del segundo argumento

  1. Array vacio. El código se ejecuta cuando se renderice por primera vez el componente.
  2. Ningún valor. El código se ejecuta cada vez que se haga render de nuestro componente o, dicho de de otra forma, cada vez que se modifique un estado.
  3. Array con elementos. Los estados que le pasemos al array harán que cuando haya un cambio en ellos se ejecutará la función.

Resumen de la clase

  • Ahora trabajaremos con los efectos en funciones y con su equivalente en React.component que son los métodos de ciclo de vida.
  • En esta clase nos enfocaremos en los efectos del componente UseState

Situacion

  • Queremos que después de 2 segundos que nuestro estado loading cambie a true por el botón vuelva a ser false.
  • No podemos simplemente escribir if(loading) setLoading(false) pues el código se va a ejecutar siempre que React haga un render del componente.
  • El render del componente se va activar con el cambio de cualquier cambio de estado.
  • Cuando se vuelve a renderizar, los estados vuelven a ser creados pero no serán el valor inicial sino el ultimo estado definido con los actualizadores

Solución
Para poder ejecutar nuestro código no en cada render sino bajo ciertas condiciones utilizamos el React.useEffects

Que clase mas cool 😎😎😎

También pueden usar async/await, para hacer el código más legible:

    useEffect(() => {
        const fetching = async () => {
            console.log("Iniciando validación");
            await sleep(1000);
            setLoading(false);
            console.log("Terminando validación");
        }
        if(!!loading){
            fetching();
        }
    }, [loading]);

Donde la función sleep es:

const sleep = async (ms) => {
    return new Promise(resolve => setTimeout(resolve, ms));
}

Pueden probar este código para revisar mas ciclos de vida, si vienen de class components o de otros framework como Angular o Vue depronto puedan relacionarlo así.
Cómo aporte adicional, como pueden ver estoy retornando una array function, esta se ejecutara cuando el componente se desmonte y cuando pase al siguiente render respectivamente. Creo que implementando el codigo y tratando de revisarlo en la consola puede quedar mas claro.

useEffect(() => {
    console.log('on component mount');
    return () => {
      console.log('on component unmount');
    }
  }, []);
  useEffect(() => {
    console.log('on component update/render');
    return () => {
      console.log('on component update/render unmount');
    }
  });
import React from "react";

function UseState({ name }) {
  const [error, setError] = React.useState(true);
  const [loading, setLoading] = React.useState(false);

  React.useEffect(() => {
    console.log("Starting the effect");

    if(!!loading) {
      setTimeout(() => {
        console.log("Doing the validation");

        setLoading(false);

        console.log("Finishing the validation");
      }, 3000);
    }

    console.log("Finishing the effect");
  }, [loading]);

  return (
    <div>
      <h2>Delete {name}</h2>

      <p>Please enter the security code</p>

      {error && (
        <p>Error: Security code is incorrect</p>
      )}
      {loading && (
        <p>Loading...</p>
      )}

      <input placeholder="Security Code" />

      <button
        onClick={() => setLoading(true)}
      >Check</button>
    </div>
  );
}

El useEffect es un hook que realiza efectos secundarios o side effects.
Un efecto secundario es una acción externa al código que se ejecuta: llamadas a API, suscripciones a eventos, actualización del DOM.

Recibe dos argumentos:

  1. la función a ejecutar
  2. un array de dependencias que determina cuándo se va a ejecutar nuestro efecto. O puede no recibir nada
    2.1) Si no recibe nada se ejecuta al primer y cada renderizado de nuestra app
    2.2) Array vacío: en el primer renderizado de nuestra app
    2.3) Array con dependencia: se ejecutará cuando se modifique dicha dependencia

3️⃣ Efectos con useEffect

Ahora trabajaremos con los efectos en funciones y con su equivalente en React.component que son los métodos de ciclo de vida

En esta clase nos enfocaremos en los efectos del componente UseState

Situacion

Queremos que después de 2 segundos que nuestro estado loading cambie a true por el botón vuelva a ser false.

No podemos simplemente escribir:

if(loading){
    setLoading(false);
}

Pues el código se va a ejecutar siempre que React haga un render del componente.
El render del componente se va activar con el cambio de cualquier cambio de estado.
Cuando se vuelve a renderizar, los estados vuelven a ser creados pero no serán el valor inicial sino el ultimo estado definido con los actualizadores

Solución

Para poder ejecutar nuestro código no en cada render sino bajo ciertas condiciones utilizamos el React.useEffects

React.useEffect es un método con 2 parámetros:

React.useEffect(() => {
    //...
},[]);
  1. El primero, siempre se usa y es una función a ejecutar.
  2. El segundo, opcional e importante, nos indica cuando se va a ejecutar nuestro primer parámetro. Los posibles valores de este parámetro son:
    • Ningun valor: esta función se ejecutará cada vez que nuestro componente haga render (es decir, cada vez que haya cambios en cualquiera de nuestros estados).
    • Arreglo vacio: **[]** nuestro efecto solo se ejecuta una vez, cuando recién hacemos el primer render de nuestro componente.
    • Arreglo no vacio: [state,error] O también podemos enviar un array con distintos elementos para decirle a nuestro efecto que no solo ejecute en el primer render, sino también cuando haya cambios en esos elementos del array.
yo quiero también un curso de optimización de render

Que bueno esta vez lo entendi perfectamente!! muchas gracias

Lo que realicé fue agregar una función para cuando se presione clic en el botón de comprobar el loading se vuelva true y dentro de useEffect agregue el callback de setTimeout en 2s para modificar el loading a false y el error a true para que muestre como falso, pero agregue un nuevo setTimeout de 3s para volver a colocar al error a false y todo quede como al principio. 😉

import React, { Fragment, useEffect, useState } from 'react';

function UseState(props){
  const [error, setError] = useState(false);
  const [loading, setLoading] = useState(false);

  const handleClick = () => {
    setLoading(true)
  }

  useEffect(() => {
    console.log('ejecutando useEffect')
      loading ?
      setTimeout(() => {
        setLoading(false);
        setError(true)
        setTimeout(() => {
          setError(false)
        }, 3000);
      }, 2000) :
      console.log('Validacion Finalizado.')
  }, [handleClick]);
  
  return (
    <Fragment>
      <h2>Eliminar {props.name}</h2>
      <p>Por favor, escribe el codigo de seguridad.</p>
      <input type="text" placeholder='Codigo de seguridad' />
      <button
        onClick={() => handleClick()}
      >
        Comprobar</button>
      {loading && <p className='bg-success'>Validando ...</p>}

      {error && <p className='bg-danger text-white'>Error: el codigo no es valido.</p>}
    </Fragment>
  );
}

export { UseState };

termine el código tal cual pero me renderiza dos veces es normal??

Presente mi primera entrevista y me preguntaron sobre optimizacion de render en react

El useState Hook de React nos permite rastrear el estado en un componente dentro de una función.

Al igual que con useState, pueden modificar el import de la siguiente forma:

import React, { useEffect } from "react";

y usar useEffect así:

useEffect(() => {
        console.log("Empezando el efecto");

        if (!!loading) {
			setTimeout(() => {
				console.log("Haciendo la Validación");
	
				setLoading(false);
	
				console.log("Terminando la validación");
	
			}, 3000);
		}
        console.log("Terminando");
    }, [loading]);

Buen repaso