No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

No se trata de lo que quieres comprar, sino de quién quieres ser. Invierte en tu educación con el precio especial

Antes: $249

Currency
$209

Paga en 4 cuotas sin intereses

Paga en 4 cuotas sin intereses
Suscríbete

Termina en:

11 Días
3 Hrs
49 Min
42 Seg
Curso de React.js

Curso de React.js

Juan David Castro Gallego

Juan David Castro Gallego

Actualizando estados desde useEffect

20/34
Recursos

Aportes 49

Preguntas 7

Ordenar por:

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

Bueno busque y lo que falta es una coma y un array,resulta que useEffect recibe un segundo parametro llamado: ‘Arreglo de dependecias’, este especifica cuando el efecto debe ser ejecutado,es por eso que al querer ejecutarlo una vez solo se deja el array vacio:

 React.useEffect(()=>{
  setTimeout(()=>{
    const localStorageItems = localStorage.getItem(itemName)
    let parsedItem;
      if (!localStorageItems) {
        localStorage.setItem(itemName, JSON.stringify(initialValue));
        parsedItem = initialValue;
      } else {
        parsedItem = JSON.parse(localStorageItems);
        setItem(parsedItem)
      }
      setLoading(false)
  },2000);
  }, [])

Asi quedaria el codigo corregido!!

Para resolver el ejercicio, solo hay que agregar al used effect un array vacio , [ ] para que no se ejecute automaticamente.

hay que colocar “,[]” para que el useEffect no caiga en un bucle infinito,
gracias por las explicaiones JDC eres un crack

De esta manera cuando carga no muestra ninguna información, así se ve más limpio el diseño. Hice un componente loading con un SVG animado para que muestre eso mientras carga. También agregué unas condicionales por que no tiene sentido que muestre el TodoCounter si no hay todos.


return (
    <div className="App">
      {!loading? <>
        <TodoSearch 
          searchValue={searchValue}
          setSearchValue={setSearchValue}
        />  
        {searchedTodos.length===0? <></>: <TodoCounter total={totalTodos} completed={completedTodos}/>}    
          <TodoList>
            {error && <p>We have an error. Refresh please!</p>}
            {!loading && searchedTodos.length===0 && <p>Make your first TODO!</p>}
            {searchedTodos.map(todo=>(
              <TodoItem
              key={todo.text} text={todo.text} completed={todo.completed} onComplete={()=>completeTodos(todo.text)} onDelete={() => deleteTodo(todo.text)}
              />
            ))}
          </TodoList>
          <CreateTodoButton/>
          </>: <Loading/>}
    </div>
  );

El error del useEffect es que falta el arreglo de dependencias que va como segundo argumento, si no le ponemos ese array vacio en este caso, causara un error algo asi como “to many renders”

El codigo quedaria algo asi:

useEffect(() => {
    // todo el codigo que esta dentro del useEffect
  }, []);

El aviso que estás viendo es una advertencia del linter (en este caso ESLint) sobre el uso del hook useEffect en tu archivo useLocalStorage.js. La advertencia indica que necesitas proporcionar una lista de dependencias para el hook useEffect para evitar una cadena infinita de actualizaciones.

Aquí tienes el código corregido con la lista de dependencias adecuada en el hook useEffect:

import React from "react";

function useLocalStorage(itemName, initialValue) {
  const [item, setItem] = React.useState(initialValue);
  const [loading, setLoading] = React.useState(true);
  const [error, setError] = React.useState(false);

  React.useEffect(() => {
    try {
      let localStorageItem = localStorage.getItem(itemName);

      let parsedItem;

      if (!localStorageItem) {
        localStorage.setItem(itemName, JSON.stringify(initialValue));
        parsedItem = initialValue;
      } else {
        parsedItem = JSON.parse(localStorageItem);
        setItem(parsedItem);
      }

      setLoading(false);
    } catch (error) {
      setLoading(false);
      setError(true);
    }
  }, [itemName, initialValue]); // Agregar itemName e initialValue como dependencias

  const saveItem = (newItem) => {
    localStorage.setItem(itemName, JSON.stringify(newItem));
    setItem(newItem);
  };

  return { item, saveItem, loading, error };
}

export { useLocalStorage };

En esta versión corregida, he añadido [itemName, initialValue] como segundo argumento al hook useEffect, lo que indica a React que debe ejecutar el efecto solamente cuando cambien itemName o initialValue. Esto previene la posibilidad de un ciclo infinito de actualizaciones.
.
By CHATGPT

A mi nunca me dio errores, nunca me habia preocupado de no ver un error .__.

Por estar jugando jajja estas clases estan demasiado buenas

, []

, [ ]

El error es más profundo de lo que parece, curioso que nadie se dio cuenta:

https://github.com/facebook/react/issues/14920

Como comentarón compañeros, es solo poner:

}, [])

Al final del useEffect 😃

Hola Comunidad Platzi! A continuación les dejo mis apuntes de las 2 últimas clases sobre estados de Carga y Error con un paso a paso de los cambios realizados en nuestros archivos y unos bonus con mi aporte personal, espero les sea de ayuda: https://drive.google.com/file/d/1_eCnRWFm5vbv4JxG57ik-jtRhESCbIMj/view?usp=sharing

Un preview del pdf:

Mis notas de useEffect:
-Efectos de react
React.useEffect(
() => {
guardamos aquí la
parte pesada o demorada
de la aplicación
},
segundo argumento, ejemplo:
[] array vacio
)

  1. Si no se pasa el segundo argumento
    deja de último lo que está dentro de
    la función, pero sigue ejecutando.

  2. Si se pasa el arreglo vacio, en el
    primer render ejecuta al igual que el caso 1, pero al causar nuevos renders como escribir en el input nunca se ejecuta de nuevo, solo se ejecuta una vez.

  3. Si pasamos un estado derivado al array, ejemplo, totalTodos, el código de la función se ejecuta cada vez que cambia el estado totalTodos.

agregar el segundo argumento

Es por este error que me acostumbré a SIEMPRE que hago un useEffect escribir primero la función con su array de dependencias y después si empezar con la lógica. ej: useEffect( ( ) => { }, \[ ] ); ahora si useEffect( ( ) => { //mi código }, \[ ] );
Hace fácil la comprensión entre líneas de código, me encanta como explica!

quiero dar mi aporte dejando el código para puedan entender un poco mejor el flujo de lo que está haciendo el profe en el localStorage

import React from "react";
import { useEffect } from "react";
//custom Hooks
export const useLocalStorage = (itemName, initialValue)=>{
    //local storage
    const item_Todos = () => {
        /**
         * Retrieves the value of an item from the local storage. If the item does not exist, it sets the initial value for the item in the local storage and returns the initial value. If the item exists, it returns the value of the item from the local storage.
         * 
         * @returns {any} The value of the item from the local storage.
         */
        let localStorageItem = JSON.parse(localStorage.getItem(itemName));
        if (!localStorageItem) {
            localStorage.setItem(itemName, JSON.stringify(initialValue));
            return (localStorageItem = initialValue);
        } else {
            return localStorageItem;
        }
    };
    //state of react
    const [item, setItem] = React.useState(initialValue);
    const [loading, setLoading] = React.useState(true);
    const [error, setError] = React.useState(false);
    //useEffect
    useEffect(()=>{
        setTimeout(()=>{
            try {
                setItem(item_Todos());
                setLoading(false);
            } catch (error) {
                setLoading(false);
                setError(true);
            }
        }, 1800);
    },[])

    //almacenamiento en local storage
    const saveItem=(newItem)=>{
        localStorage.setItem(itemName, JSON.stringify(newItem));
        setItem(newItem);
    }
    return {item, saveItem, loading, error}
}

Creo que el error es que hizo falta el [ ].

The useEffect hook in React can be used both inside a component and inside a custom hook. However, there are some differences in how they are used and their intended purposes.

When useEffect is used inside a component, it allows you to perform side effects directly within that component. Side effects can include things like fetching data, subscribing to events, or updating the DOM. The useEffect hook inside a component is tied to the lifecycle of that component and will run every time the component is rendered or re-rendered.

On the other hand, when useEffect is used inside a custom hook, it allows you to encapsulate reusable logic and side effects. Custom hooks are a way to share stateful logic between different components without duplicating code. The useEffect hook inside a custom hook is not tied to any specific component’s lifecycle. Instead, it will be called every time a component that uses the custom hook is rendered or re-rendered.

In summary, when useEffect is used inside a component, it is specific to that component’s lifecycle. When useEffect is used inside a custom hook, it is reusable and can be used by multiple components. The behavior of useEffect is the same in both cases, but its usage and purpose are different.

🟢 Les comparto este blog sobre el error 'React hook `useEffect` has a missing dependency', <https://kinsta.com/knowledgebase/react-hook-useeffect-has-a-missing-dependency/>

La solución es colocar. Al final , [ ].

Falto el \[ ] del useEffect
El que faltará el `[]` me estaba dando una crisis, en mis pensamientos decía “Juan falta el `, []`!“ jajajaja

Hola, en mi caso agregue esto: , [itemName, initialValue]); para quitar 1 warning.

import React from "react";

function useLocaStorage(itemName, initialValue) {

  const [item, setItem] = React.useState(initialValue);

  const [loading, setLoading] = React.useState(true);

  const [error, setError] = React.useState(false);

    React.useEffect(() => {
      setTimeout(() => {
        try { 
          const localStorageItem = localStorage.getItem(itemName);
    
          let parsedItem;
      
            if (!localStorageItem) {
              localStorage.setItem(itemName, JSON.stringify(initialValue));
              parsedItem = initialValue;
            } else {
              parsedItem = JSON.parse(localStorageItem);
              setItem(parsedItem);
            }
      
            setLoading(false);
      
        } catch(error) {
          setLoading(false);
          setError(true);
        }
      }, 2000);
    }, [itemName, initialValue]);
  
    const saveItem = (newItem) => {
      localStorage.setItem(itemName, JSON.stringify(newItem));
      
      setItem(newItem);
    };
  
    return {item, 
    saveItem,
    loading,
    error,
    };
  
}

export {useLocaStorage};
Protectores de estado en React: * Nada, siempre se ejecuta el efecto. * \[], el efecto se ejecuta solo una vez. * \[something]: el fecto se ejecuta cada que something se actualiza.

Yo lo olvide pero mientras mencionaba que el useEffect seguia siendo infinito recorde que faltaba el array vacio 🤣🤣🤣

React.useEffect(()=>{
    setTimeout(()=>{
      try {
        const localStorageItems = localStorage.getItem(itemName);
        
        let parsedItem;
        
        if (!localStorageItems) {
          localStorage.setItem(itemName,JSON.stringify(initialValue));
          parsedItem = initialValue;
        }else{
          parsedItem = JSON.parse(localStorageItems);
          setItem(parsedItem)
        }
        setLoading(false);
      } catch (error) {
        setLoading(false);
        setError(true);
      }
    }, 2000
    );
  },[]);

jajajajajajajaj “ven te lo muestro” la cara que hace este tipo es genial jajajajajajajajaja

Hola! este es mi aporte,

React.useEffect(() => {
    try {
      const localStorageItem = localStorage.getItem(itemName)

      let parsedItem

      if (!localStorageItem) {
        localStorage.setItem(itemName, JSON.stringify(initialValue))
        parsedItem = initialValue
      } else {
        parsedItem = JSON.parse(localStorageItem)
        setItem(parsedItem)
      }
      setLoading(false)
    } catch (error) {
      setLoading(false)  
      setError(true)
    }
    // setTimeout(()=>{
      
    // }, 2000)
  }, [])

como pueden ver comente el setTimeout, y el try lo saque y ya no sale el error que renderiza infinitamente

[ ] un array vacio

Le faltan los corechetes al useEffect()

, [ ]

Vi el Video de Nuevo y efectivamente me di cuenta que falto el segundo parámetro que es un array vacío

aqui mi solucion

React.useEffect(() => {
        setTimeout(() => {
            try{
                const localStorageItem = localStorage.getItem(itemName);
            
                let parsedItem;
    
                if(!localStorageItem){
                localStorage.setItem(itemName, JSON.stringify(initialValue));
                parsedItem = initialValue;
                }else {
                parsedItem = JSON.parse(localStorageItem);
                setItem(parsedItem);
                }
    
                setLoading(false);
            } catch (error){
                setLoading(false);
                setError(true);
            }
        }, 2000);
    }, []);

bueno el error esta, en no poner un segundo parametro en el useEffect que seria estos 3 caracteres, “,[ ]” me refiero a un array vacio para que se ejecute una sola vez

el error está entre la computadora y la silla
Por cada useEffect, debe haber un array al final, ya sea vacio, o dentro, con la variable a la que cada vez que se actualize, se actualize el estado igual. En mi caso yo lo habia creado ya asi, por ende no hubo error xDDD
esto \[]
Codigo final `  React.useEffect(() => {` `    setTimeout(() => {` `      try {        const localStorageItem = localStorage.getItem(itemName);        let parsedItem;            if (!localStorageItem) {          localStorage.setItem(itemName, JSON.stringify(initialValue));          parsedItem = initialValue;        } else {          parsedItem = JSON.parse(localStorageItem);        }            setItem(parsedItem);        setLoading(false);          } catch (error) {        setLoading(false);        setError(error);      }          }, 2000);` `  }, []);`
*useEffect*(() => { initialize\_item(); }, \[]);
El reto esta en que nuestro useEffect debe contener un estado de loading, ya que es el unico que cambia si se ejecuta la peticion correcta o incorrecta y por tanto solo se ejecutaria 1 sola vez cuando deje de cargar ![](https://static.platzi.com/media/user_upload/image-6595259c-b2a3-447e-afbe-3514e6fe1b6f.jpg)
Yo puse dentro del try un console.log y al ver que se seguia ejecutando esta vez cada dos segundos, puse el segundo parametro del useEffect que se ejecute cuando haya algun cambio en item
Comparto mis apuntes echos en Notion :3 Si tengo errores en los conceptos o términos que usé, porfa haganmelo saber ![](https://static.platzi.com/media/user_upload/imagen-d0f4a0e5-e194-45ac-9abc-e584e4405f5f.jpg)
\[]
Como vinos en la clase pasada, falta el Array vacio \[ ] para decirle que solamente se ejecute cuando el array cambia.

Yo hice quizá una pendejada, pero me pareció interesante y es que al recargar la página, el título que contiene el componente TodoCounter decía que ya había completado los TODOs, de acuerdo a un reto de clases pasadas, pero no era cierto, por lo que use el estado de loading como prop desde el componente para validar si estaba cargando, cambiara el título por uno de carga.

Les dejo el código por si quieres chekearlo.

import './TodoCounter.css'
function TodoCounter({ total, completed, loading }){

    let content;

    if (loading == true){
      content = (<h1 className="TodoCounter">
      Estamos cargando los resultados...
      </h1>
      );

    } else if (total === completed) {
      content = (<h1 className="TodoCounter">
        ¡Felicitaciones, completaste todos los TODOs!
        </h1>
      );

      } else {
      
      content = (<h1 className="TodoCounter">
        Has completado <span>{completed}</span> de <span>{total}</span> TODOs
        </h1>
      );
      
      }
      
    return content;
  }

export { TodoCounter };

![](

yo resolveria el problema con un booleano, de que loading = false, luego se mete al bucle y ya lo hago true, y afuera tengo un if, que si es true ya no se cumpla. es una solucion muy floja jajaja xd, tengo sueño :p