No tienes acceso a esta clase

隆Contin煤a aprendiendo! 脷nete y comienza a potenciar tu carrera

Curso de React.js

Curso de React.js

Juan David Castro Gallego

Juan David Castro Gallego

Actualizando estados desde useEffect

20/34
Recursos

Aportes 30

Preguntas 4

Ordenar por:

驴Quieres ver m谩s aportes, preguntas y respuestas de la comunidad?

o inicia sesi贸n.

Bueno busque y lo que falta es una coma y un array,resulta que useEffect recibe un segundo parametro llamado: 鈥楢rreglo 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!!

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>
  );

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

, []

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

, [ ]

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:

agregar el segundo argumento

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

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

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 鈥渢o 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

Por estar jugando jajja estas clases estan demasiado buenas

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

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.

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鈥檚 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鈥檚 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.

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 鈥渧en 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()

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.

, [ ]

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

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};

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