Introducción al curso avanzado de React

1

Qué necesitas para este curso y qué aprenderás sobre React.js

2

Proyecto y tecnologías que usaremos

Preparando el entorno de desarrollo

3

Clonando el repositorio e instalando Webpack

4

Instalación de React y Babel

5

Zeit es ahora Vercel

6

Linter, extensiones y deploy con Now

Creando la interfaz con styled-components

7

¿Qué es CSS-in-JS?

8

Creando nuestro primer componente: Category

9

Creando ListOfCategories y estilos globales

10

Usar información real de las categorías

11

Creando PhotoCard y usando react-icon

12

SVGR: de SVG a componente de ReactJS

13

Creando animaciones con keyframes

Hooks

14

¿Qué son los Hooks?

15

useEffect: limpiando eventos

16

useCategoriesData

17

Usando Intersection Observer

18

Uso de polyfill de Intersection Observer e imports dinámicos

19

Usando el localStorage para guardar los likes

20

Custom Hooks: useNearScreen y useLocalStorage

GraphQL y React Apollo

21

¿Qué es GraphQL y React Apollo? Inicializando React Apollo Client y primer HoC

22

Parámetros para un query con GraphQL

23

Usar render Props para recuperar una foto

24

Refactorizando y usando variables de loading y error

25

Usando las mutaciones con los likes

Reach Router

26

¿Qué es Reach Router? Creando la ruta Home

27

Usando Link para evitar recargar la página

28

Creando la página Detail

29

Agregando un NavBar a nuestra app

30

Estilando las páginas activas

31

Rutas protegidas

Gestión del usuario

32

Introducción a React.Context

33

Creación del componente UserForm; y Hook useInputValue

34

Estilando el formulario

35

Mutaciones para registro

36

Controlar estado de carga y error al registrar un usuario

37

Mutaciones para iniciar sesión

38

Persistiendo datos en Session Storage

39

Hacer like como usuario registrado

40

Mostrar favoritos y solucionar fetch policy

41

Cerrar sesión

Mejores prácticas, SEO y recomendaciones

42

Últimos retoques a las rutas de nuestra aplicación

43

React Helmet

44

Midiendo el performance de nuestra app y usando React.memo()

45

React.lazy() y componente Suspense

46

Usando PropTypes para validar las props

47

PWA: generando el manifest

48

PWA: soporte offline

49

Testing con Cypress

Conclusiones

50

¡Felicidades!

No tienes acceso a esta clase

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

Curso de React Avanzado

Curso de React Avanzado

Miguel Ángel Durán

Miguel Ángel Durán

Usando el localStorage para guardar los likes

19/50
Recursos

Aportes 25

Preguntas 2

Ordenar por:

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

o inicia sesión.

Le falto el JSON.parse(like) cuando obtiene el valor del local storage, de lo contrario siempre que le das like a una foto no volvera a false, porque lo que retorna es un string con el valor “false” hay que parsearlo para que lo lea, al principio funciona ya que los valores que devuelven son null! (osea falsos)

const [liked, setLiked] = useState(() => {
    try {
      const like = window.localStorage.getItem(key)
      return JSON.parse(like)
    } catch (e) {
      console.log('error!!', e)
    }
  })

Igual excelente curso!!

Los iconos también los pueden estilizar directamente con styled components

import styled from 'styled-components'
import { MdFavorite } from 'react-icons/md'

export const LikeIcon = styled(MdFavorite)`
  color:  #ff277a;
  ${fadeIn({ time: '250ms', type: 'ease-in' })}
`

Hasta este punto, el proyecto funciona la primera vez que lo ejecutas y luego los corazones nunca vuelven a ser false.

Para solucionarlo, deben hacer lo siguiente:

const [liked, setLiked] = useState(() => {
    try {
      const like = window.localStorage.getItem(key)
      return JSON.parse(like)
    } catch (e) {
      console.log('error!!', e)
    }
  })```

al quitar el me gusta no funciona seguía mostrando los me gusta… solución

const [liked, setLiked] = useState(() => {
        try {
            const like = window.localStorage.getItem(key)
            
            if (like == 'true') {
                return like
            }
            return false
                
        } catch (e) {
            return false
        }
    })

Brutal, en definitiva uno de los mejores profesores que me he topado en platzi, que maestro!

Para guardar el valor cuando le das Unlike, simplemente agregamos una ternaria

 const  setLocalStorage = value => {
    try{
      value ? window.localStorage.setItem(`like_${id}`,value)
           : window.localStorage.removeItem(`like_${id}`,value)

      setLiked(value);

    }catch(e){
      console.error(e)
    }
  }

Para agregar color rojo al liked y una pequeña animacion.

            <Button liked={liked} onClick={() => setLocalStorage(!liked)}>
              <Icon size='32px' /> {likes} likes!
            </Button>
export const Button = styled.button`
  display: flex;
  align-items: center;
  padding-top: 8px;
	width: 100%;
	padding: 0 15px;
	box-shadow: 0 30px 35px #e5e5e5;
	border-bottom-right-radius: 10px;
	border-bottom-left-radius: 10px;
  & svg {
    margin-right: 4px;
		color: #d1d1d1;
    width: 23px;
    ${
      props => props.liked && css`
        ${fadeIn()}
        color: red`
    }
  }
`

Los valores almacenados en localStorage se pueden ver en el inspector (devTools) en …

En las versiones más recientes de EcmaScript ya no hace falta incluir (e) en el catch si este no se va a usar (o no nos interesa manejar el error de manera específica), así que podemos usar solo } catch {

Si les sale el error:

Too many re-renders. React limits the number of renders to prevent an infinite loop

No se preocupen, en la próxima clase con el refactor que se hace, queda solucionado ✌️

Crack!! 👏👏

Este proceso está super genial, pero en un proyecto real usaríamos una peticion de tipo post (si el api es REST) y todos esos likes los recuperariamos del api… No?

Consulta, a modo de escalabilidad (por cuestiones de rendimiento si nos encontramos en algún proyecto más grande) en cuanto a la función de onClick, es igual poner

<Button onClick={() => setLocalStorage(!like)} />

A intentar no utilizar dentro de los componentes las arrow functions y utilizar algo como

setLocalStorage = () => {
 const value = !like
 ...
}
<Button onClick={setLocalStorage} />

¿Sería lo mismo o la segunda forma si mejora un poco a la larga la performance de nuestra App?
Gracias!

Respecto el uso de una función en useState y el porqué:

El parámetro que le pasamos a useState es “ìnitialState”, éste sólo se utiliza en el primer render, pero si no lo pasamos dentro de una función, entiendo que se ejecutaría en cada render si extraemos el valor directamente, es decir, estaríamos ejecutando cada vez window.localStorage.getitem:

useState(window.localStorage.getItem(key))

En cambio si usamos una función, como nos presenta el video, ésta solo se ejecuta en el primer render, y así sólo ejecutamos window.localStorage.getItem 1 vez.

He aquí el porqué la documentación oficial menciona que si requerimos una computación pesada (yo diría cualquier computación), mejor usar una función.

Aún me queda la duda de si sería más eficiente definir una function getLocalStorage() fuera del componente para así evitar estar definiendo una función en cada render, o si la máquina V8 es lo suficientemente inteligente/optimizada para que sea irrelevante.

No sería mejor guardar un array o un objeto que contenga los likes dentro del local Storage?, para no guardar N keys distintas, guardar una única que contenga todos.

Dado que hoy en día existen múltiples implementaciones nativas de IntersectionObserver, el polyfill que antes se mantenía en este repo ya no está soportado y ha sido archivado

Genial

Una funcionalidad de uso común compleja, pero con esta clase te simplifica la vida

me gusta esta explicacion acerca del localStorage
https://www.youtube.com/watch?v=hb8O0qRqiSk&ab_channel=FernandoHerrera

Genial buen tip, el de poner Try Catch al setear o recuperar del localStorage, no contemplaba cuando un usuario entra en modo privado…

Bien, esto es solo algo provisional después veremos como guardar esta información en la base de datos

me funcionó solo cerrando con eval(), la obtención del item.

const [liked, setLiked] = useState(() => {
        try {
            return eval(window.localStorage.getItem(key));
        } catch (error) {
            console.log(error);
            return false;
        }
    });    

Algo que a primeras vistas tiene un contexto complejo, se muestra simple para miras a un cliente

Hola, les dejo el avance de mi repositorio hasta acá hecho en Nextjs:

https://github.com/danyel117/petgram-platzi/tree/localstorage

Aplicando lógica, muy interesante, como podemos grabarnos tantas palabras claves y útiles y que las recordemos a la hora de usarlas?