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!

Curso de React Avanzado

Curso de React Avanzado

Miguel Ángel Durán

Miguel Ángel Durán

¿Qué son los Hooks?

14/50

Lectura

¡Un saludo, Platzinauta!👋🏻

¡Ups! De momento esta clase no está disponible en nuestra plataforma, pero sí la tenemos en YouTube.

Para no interrumpir tu aprendizaje te dejamos el video y link para que puedas verla en YouTube.

Link a YouTube

Pronto estará disponible en Platzi como el resto de clases.

Gracias por tu comprensión y nunca pares de aprender. 💚

Aportes 63

Preguntas 15

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad? Crea una cuenta o inicia sesión.

El profe se quedó suspendido sonriendo al final como por 10 segundos :v

para los que gusten hacer el ejemplo con async/await se puede hacer de la siguiente manera

 useEffect(() => {
    const fetchCategories = async () => {
      const response = await window.fetch(
        'https://petgram-server-edsf8xpy2.now.sh/categories'
      )
      const data = await response.json()
      setCategories(data)
    }

    fetchCategories()
  }, [])

cabe acotar que async await no funciona de manera directa, tenemos que instalar

npm install @babel/plugin-transform-runtime --save-dev

y anexarlo en el apartado de options de nuestre webpack

options: {
            presets: ['@babel/preset-env', '@babel/preset-react'],
            plugins: [
              ['@babel/plugin-transform-runtime', { regenerator: true }]
            ]
          }

Para todos los que tienen problemas al generar la API de Categorías, les dejo este pequeño aporte:
1) En la terminal, ingresan a la carpeta api

2) Ejecutan el comando vercel

3) Al compilar el proyecto genera una URL Preview sombreada en amarillo en la Imagen, dar click en esa URL, el cual les abrirá en el navegador.

4) Agregan la palabra categories después de la Url y les abrirá la información de las categorías. Esa url es la que van a copiar en el proyecto.

¿Qué son los Hooks?
Funciones que nos permiten acceder a casi todas las características de react desde componentes funcionales.
Las características que por ahora no se pueden acceder son:
getSnaphotBeforeUpdate
componentDidCatch
🔧
Los hooks principales son
- useState: para añadir un estado local en el componente
- useEffect: permite ejecutar una funcion cada vez que rendericemos nuestro componente
- useContext: permite acceder a la context API para obtener valores que se utilizaran en toda la aplicacion de forma global, sin necesidad de pasarla por las props.

Para generara la url solo debes ir a la carpeta API desde la terminal

  1. cd API
  2. en la terminal escribes vercel
    Te saldra asi ✅ Preview: https://petgram-server-leidy-daza.leidydaza.vercel.app [31s]
    solo debemos agregar categories al final de la url y listo
    https://petgram-server-leidy-daza.leidydaza.vercel.app/categories

Al inicio tuve problemas con esto y era porque no sabia que habia que subir a now la parte del API, espero si otros se encuentran con este mismo problemas que no les trae las categorias, tienen que subir el API donde esta el grahql y en la ruta que les da el now traer las categorias, en mi caso fue asi:

https://petgram-server-24iykciv5.now.sh/categories

Saludos!

Los Hooks son un conjunto de funciones que son una alternativa a setState, componentDidMount, componentDidUpdate, etc.

¿Prefieres usar async await?

Te dejo mi commit para que veas la configuración que se tiene que hacer.

Se puede usar el async await, en vez de las promises en el useEffect hook de esta forma.

  1. Se crea una función dentro el useEffect y luego inmediatamente se llama a function.

caveats: useEffect no puede retornar nada, así que no se puede usar el async directo en el.

  useEffect(() => {
    async function fetchData() {
      const result = await fetch(
        'URL-A-CONSULTAR'
      )
      const data = await result.json()
      setcategories(data)
    }
    fetchData()
  }, [])```

La sacó del estadio con ese array vacío como segundo parámetro en el useEffect, yo no vi eso en la documentación.
Yo usaba un filtro con un condicional para que no hiciera hiciera el fetch infinitamente.
Con eso ya valió lo que pagué en Platzi jajajaja

React Hooks

.
Los hooks son funciones que nos permiten acceder a casi todas las características de React desde componentes funcionales, le dan estado y ciclo de vida a los componentes de tipo función o StateLess.
.
El Hook useState: nos devuelve un array con dos elementos: la primera posición es el valor de nuestro estado, la segunda es una función actualizadora que nos permite modificar ese valor.
.

import React,{useState} form 'react';
const [videos, setVideos] = useState({});

El Hook useEffect: va a manejar mis transmisiones, puedo hacer peticiones de una API o algún evento que se tenga que transmitir dentro de nuestros componentes, así como listeners que escuchen algún cambio que vaya a ser necesario
.

  useEffect(() => {
    window.fetch('https://petgram-server.behagoras.now.sh/categories')
      .then(res => res.json())
      .then(response => setCategories(response))
  }, [])

.
Una de las características más importantes de UseEffect es que permitirá ejecutar código cuando se monta, desmonta o actualiza nuestro componente

async / await
**npm i -D @babel/runtime @babel/plugin-transform-runtime **

useEffect(() => {
    const getCategories = async () => {
      let response = await fetch(`${URL_API}/categories`);
      response = await response.json();
      setCategories(response);
    };
    getCategories();
  }, []);

😀👋🏻Hola!
Para sacar el link con el json:

  • Entras desde la terminal en la carpeta /api/ del proyecto

  • Allí ejecutas vercel

  • Copias la url que te da y le agregas /categories en el navegador

Hooks Principales

  • useState
    • Añadir un estado local en el componente
  • useEffect
    • Ejecutar una función cada vez que renderizemos nuestro componente
  • useContext
    • Nos va permitir acceder a la context API para obtener valores que utilizaremos en toda nuestra aplicación de forma global sin necesidad de pasarla por la props

Me parece que cuando compararon los códigos con y sin Hooks hubo mucho más salto de carro en el ejemplo sin Hooks, lo que visualmente genera algo de sesgo. Nada contra la feature, solo encontré algo tendenciosa la comparación. Eso…

getSnapshotBeforeUpdate() se invoca justo antes de que la salida renderizada más reciente se entregue, por ejemplo, al DOM. Permite al componente capturar cierta información del DOM (por ejemplo, la posición del scroll) antes de que se cambie potencialmente. Cualquier valor que se devuelva en este ciclo de vida se pasará como parametro al método componentDidUpdate().
Este caso de uso no es común, pero puede ourrir en IUs como un hilo de chat que necesita manejar la posición del scroll de manera especial.

componentDidCatch()
Este ciclo de vida se invoca después de que un error haya sido lanzado por un componente descendiente. Recibe dos parámetros:

  1. error - Es un error que ha sido lanzado.
  2. info- Un objeto con una clavecomponentStack contiene información sobre que componente ha devuelto un error.
    componentDidCatch() se llama durante la fase “commit”, por lo tanto, los efectos secundarios se permiten. Debería utilizarse para cosas como errores de registro:

para que podamos obtener las ctaegorias debemos dirigirnos a la carpeta api desde la terminal, luego ejecutamos el comando vercel, y finalmente nos dara una url https://petgram-server-mcvictor.mcvictormurillo.vercel.app porteriormente agregamos el /categories https://petgram-server-mcvictor.mcvictormurillo.vercel.app/categories y listo

Una versión con async await y ejecutando el fetchData en si mismo.

import React, { useState, useEffect } from 'react'
import { Category } from '../Category'
import { List, Item } from './styles'

export const ListOfCategories = () => {
  const [categories, setCategories] = useState([])

  useEffect(() => {
    ;(async function fetchData () {
      const response = await fetch(
        'https://proyect-rn-petgram.now.sh/categories'
      )
      const data = await response.json()
      setCategories(data)
    })()
  }, [])

  return (
    <List>
      {categories.map(category => (
        <Item key={category.id}>
          <Category {...category} />
        </Item>
      ))}
    </List>
  )
}```

ListOfCategories/index.js

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

import {List, Item} from './styles';

import { Category } from '../Category';

export const ListOfCategories = () => {
    const [categories, setCategories] = useState([]);

    useEffect(function(){
        window.fetch('https://petgram-server-alejandroverita-alejandroverita.vercel.app/categories')
            .then(res => res.json())
            .then(data => {
                setCategories(data)
        })
    }, [])

    
    return (
        <List>
            {
                categories.map(category => 
                    <Item key = {category.id}>
                        <Category {...category} />
                    </Item>
                )
            }
        </List>
    )
}

Una pregunta, que pasa con las otras características de react como el manejor delos metodos de vida de un componente (componentDidMount, etc) con un componente con hooks? y si se puede seguir usando el paradigma de separar la parte logica (containers) y la parte visual (Presentational Components) con los hooks? gracias de antemano!

Si estas viendo esto en el 2022, para poder tener la lista de categories, realmente la tienes que deployar y tener en un proyecto diferente del principal, porque cada que haces deploy de la rama main, se borra lo que hay en la url de /categories.
Lo que yo hice fue lo siguiente:

  1. irem al directorio api > cd api
  2. renombrar el archivo now.json por vercel.json
  3. en builds deben remplazar now por vercel asi > “builds”: [{ “src”: “index.js”, “use”: “@vercel/node” }]
  4. en los scripts de package.json en donde dice “deploy”: “now -t <tu-token>” remplazar now por vercel y que quede asi > “deploy”: “vercel -t <tu-token>”
  5. estando en la terminal en la ubicacion de api ejecutar el siguiente comando > vercel
  6. Cuando te haga las preguntas > Which scope do you want to deploy to? elijes tu usuario
    Link to existing project?, le pones que no con la n, What’s your project’s name?, le das enter para que le deje el que te sugiere petgram-server, In which directory is your code located?, le das enter con la ubicacion que tu sugiere y listo
  7. copias la url que dice Preview y le agregas el endpoint /categories

Para los que tengan problemas con encontrar las categorías en vercel, suban la carpeta API desde la terminal a vercel y ya esta.

Para los que no les corra el link de las categories, basta con ir a la api (en la terminal poner cd api) y darle vercel. luego de eso te hará el despliegue y añades el /categories en el link

Con axios y async/await es6

const getData = async () => {
    try {
        const res = await axios.get('https://petgram-server-paolo.vercel.app/categories');
        const { data } = await res;
        return data;
    } catch (err) {
        console.error(err);
    }
};
const ListOfCategories = () => {
    const [categories, setCategories] = useState([]);

    useEffect(
        async () => {
            const data = await getData();
            setCategories(data);
        }
    ,[]);
.....
}

No funciona con async await 😦

Ayuda el curso esta caido

Exelente! Qué tal si queremos hacerlo con una función asíncrona? He notado que utilizando Async/Await la consola devuelve este Error " regeneratorRuntime is not defined
".

const [categories, setCategories] = useState([])
  useEffect(() => {
    getData(API)
  }, [])
  const getData = async (URL) => {
    const data = await window.fetch(URL)
    			.then((res)=>res.json()).catch((err) => err)
    setCategories(data)
  }

HE INTENTADO HACER ESTO MISMO CON ASYNC/AWAIT Y ME DA ESTE ERROR Uncaught ReferenceError: regeneratorRuntime is not defined

export const ListOfCategories = () => {
  const [categories, setCategories] = useState([])

  useEffect(async function () {
    const data = await window.fetch('https://petgram-server-culito.now.sh/categories')
    const response = await data.json()
    setCategories(response)

    /* window.fetch('https://petgram-server-culito.now.sh/categories')
      .then(res => res.json())
      .then(response => { setCategories(response) }) */
  }, [])

Que debo hacer para subir la api a now ?

Si estas viendo esto en el 2022, la URL que aparece en el vídeo no funciona, pero gracias a los comentarios he encontrado esta:

https://petgram-server-alejandroverita-alejandroverita.vercel.app/categories

por si no sabes donde ponerla este es el useEffect sin importar al principio de la línea:

React.useEffect(function(){
fetch(‘https://petgram-server-alejandroverita-alejandroverita.vercel.app/categories’)
.then(res => res.json())
.then(response =>{
setCategories(response)
})
.catch(error => console.log(error))
}, []);

DEBERÍAN DE ACTUALIZAR ALGUNOS CURSOS.

Que miedo da midu los ultimos 10 segundos 0.o

Genial

import React, { useEffect, useState } from "react";
import axios from "axios";
import { Category } from "../Category";

import { List, Item } from "./styles";

export const ListOfCategories = () => {
  const [categories, setCategories] = useState([]);

  useEffect(() => {
    const fetchCategories = async () => {
      const { data } = await axios.get(
        "https://petgram-server-dagibu.vercel.app/categories"
      );
      setCategories(data);
    };

    fetchCategories();
  }, []);

  return (
    <List>
      {categories.map((category) => (
        <Item key={category.id}>
          <Category {...category} />
        </Item>
      ))}
    </List>
  );
};

si prefieres con axios, que tal asi?

useEffect(() => {
    axios.get(URL)
      .then((res) => {
        setCategories(res.data)
      })
  }, [])

Esta es la mayor explicacion de hooks que he tenido. Muchas gracias.

Genial la manera de explicar y escribir código. hay temas que en otros cursos no explican y aquí queda todo claro.

maravilloso, ahora sé para que se usan los corchetes dentro de useEffect al final. [] = para ejecutar una vez el efecto.

al yo hacer setCatetgories( ) automaticamente renderizo todo mi componente, y se carga todo nuevamente, y como el useEffect no tiene un arreglo vacío de dependencias, pues se vuelve a ejecutar y ejecuta el setCategories que a su vez vuelve a renderizar y por eso se crea un ciclo infinito

Me está pasando esto al hacer el fetch a la api externa.

Usar clases entonces queda obsoleto?

Se puede utilizar async/await de en el hook useEffect también de esta forma:

useEffect(async () => {
    await window.fetch('https://petgram-server-test.vercel.app/categories')
      .then(res => res.json())
      .then(response => {
        setCategories(response)
      })
  }, [])

y se realiza como indica un compañero en su aporte más abajo la instalación del paquete

npm install @babel/plugin-transform-runtime --save-dev

y se anexa al option del webpack.config.js la siguiente configuración

options: {
            presets: ['@babel/preset-env', '@babel/preset-react'],
            plugins: [
              ['@babel/plugin-transform-runtime', { regenerator: true }]
            ]
          }

para los que usamos async/await con webpack y babel se requiere hacer dos cosas
1.

npm install --save @babel/polyfill
  1. Al principio del archivo webpack en el objeto module.export, agrega lo siguiente
    entry: ["@babel/polyfill", “<your enter js file>”]
    debe quedar así
module.exports = {
  mode: 'development',
  entry: ['@babel/polyfill', './src/index.js'],

Con eso funcionará

Ayuda! me salta Uncaught ReferenceError: regeneratorRuntime is not defined 😕

Aqui como hacerlo con async/await

![](

Los hooks prácticamente nos libran de utilizar tantas clases y nos permite aplicar las bondades del State y Render de React en una función

Interesante clase. Tuve error del fetch infinito cuando probé por primera vez useEffect.

Hola, tengo un problema con el fetch, no me carga las categorías, también me muestra un error en consola adjunto mi código y configuración de now.json. Estuve probando por horas; pero no me sirvió:(

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

import {Category} from '../category/category';
import {List, Item} from './styles_list';
//import {categories as mockCategories} from '../../api/db.json';

export const ListOfCategories =()=>{
    const [categories, setCategories] = useState([])

// async function fetchData(){
//     const res = await fetch("https://petgram.ronaldnolascou.now.sh/categories");
//     res.json();
// }

// useEffect(()=>{
//     fetchData();
// });

// useEffect(()=>{
//     async function fetchData(){
//         const res = await fetch('https://petgram-server.ronaldnolascou.now.sh/categories')
//         const data = await res.json()
//         setCategories(data)
//     }
//     fetchData()
// },[])



    useEffect(function(){
        fetch('https://petgram.ronaldnolascou.now.sh/categories')        
        .then(res =>res.json())
        .then(response =>{setCategories(response)
    })},[]);
        return(
            <List>
               {
                    categories.map(category => <Item key={category.id}><Category {...category}/></Item>)
               } 
            </List>
        )
}

now.json:

{
    "version": 2,
    "name": "petgram",
    "alias": [
        "petgram-api"
    ],
    "builds": [
        {
            "src": "index.js",
            "use": "@now/node"
        }
    ],
    "routes": [
        {
            "headers": {
                "Access-Control-Allow-Origin": "*",
                "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS",
                "Access-Control-Allow-Headers": "X-Requested-With, Content-Type, Accept"
            },
            "src": "/.*",
            "dest": "index.js"
        }
    ]
}```

profundizando mas en useReducer, cual es la falla con este codigo?
Se que es un pos incremento, pero cuando reviso el estado desde la consola, nunca se agrega el incremento despues del return.

import React, { useReducer } from "react";
import "../../styles/css/machucame.css";

function reducer(state, action) {
  switch (action) {
    case "increase":
      if (state.count > 9) {
        return { count: 0 };
      } else {
        return { count: state.count++ };     //no se agrega el incremento en el estado despues del return 
      }

    case "decrease":
      return { count: state.count - 1 };
    default:
      console.log("press error");
  }
}

function Machucame(props) {
  const [count, dispatch] = useReducer(reducer, { count: 0 });

  return (
    <div className="padre">
      <div className="cuadro">
        <h1>{props.children}</h1>
        <button onClick={props.toggle} className="button">
          {props.message.toUpperCase()}
        </button>

        {count.count}
        <div className="buttonContainer">
          <button
            onClick={() => {
              dispatch("increase");
            }}
            className="button"
          >
            Increase
          </button>
          <button
            onClick={() => {
              dispatch("decrease");
            }}
            className="button"
          >
            Decrease
          </button>
        </div>
      </div>
    </div>
  );
}
export default Machucame;

se que se puede solucionar este error con un state.count + 1 y hasta con un ++state.count, pero no entiendo porque no funciona con el pos incremento despues de devolver el return, quizas tenga algo que ver con el return

Gracias a los hooks me acostumbre a destructurar todo lo que toco!

Hooks Principales
useState. Para añadir un estado local en nuestro componente.
useEffect. Nos permite ejecutar una función cada vez que rendericemos nuestro componente.
useContext. Nos permite acceder a la context XBI para tener valores que utilizaremos en toda nuestra aplicación en forma global sin necesidad de pasarla por las props.

Hooks Auxiliares
useReduce. Nos permite actualizar el estado de nuestro componente.
useCallback. Devolverá una versión memorizada del callback que solo cambia si una de las dependencias ha cambiado.
useMemo. Solo volverá a calcular el valor memorizado cuando una de las dependencias haya cambiado. Esta optimización ayuda a evitar cálculos costosos en cada render.
useRef. Nos permite coger referencias de los elementos del DOM.
useImperativeHandle. Personaliza el valor de instancia que se expone a los componentes padres cuando se usaref.
useLayaoutEffect. Se ejecuta de forma sincrónica inmediatamente después de que React haya realizado todas las mutaciones DOM. Esto puede ser útil si necesita realizar mediciones DOM (como obtener la posición de desplazamiento u otros estilos para un elemento) y luego realizar mutaciones DOM o desencadenar una reproducción sincrónica actualizando el estado.
useDebugValue. Nos permite en nuestro desarrollo acceder a valores sin tener que poner console.log
https://es.reactjs.org/docs/hooks-reference.html#usecallback

Hola, no logro hacer el deploy para tener disponible la url de mi servidor ( /categories).
El deploy que hice me sirvió para ver en otra url mi aplicación, alguien me podría ayudar?
Utilicé Vercel ya que Now no es más Now

Custom hook useCategories

import { useState, useEffect } from 'react'

export const useCategories = () => {
  const [categories, setCategories] = useState([])

  useEffect(() => {
    window.fetch('https://petgram-server-edsf8xpy2.now.sh/categories')
      .then(response => response.json())
      .then(data => {
        setCategories(data)
      })
  }, [])

  return {
    categories
  }
}

ListOfCategories

import React from 'react'
import { Category } from '../Category'
import { List, Item } from './styles'
import { useCategories } from '../../hooks/useCategories'

export const ListOfCategories = () => {
  const { categories } = useCategories()
  return (
    <List>
      {
        categories.map(category => <Item key={category.id}><Category {...category} /></Item>)
      }
    </List>
  )
}

Hola Devs:
-Para los que necesiten el link del API aqui esta: Click Aqui
Recuerden, #NuncaParesDeAprender 💚

Interesante clase. Excelente manera de explicar que son los Hooks.

Aquí hay un pequeño articulo que explica el array de dependencias: https://dev.to/rozenmd/understanding-useeffect-the-dependency-array-obg

Me cuesta aún la curva de los Hooks, creo que debe ser demasiada práctica

Alguien sabe si este código esta bien?

el código que el profesor dejo en archivos y enlaces ya no esta la lineal 4.

Que diferencia tengo usando Hooks en vez de usar el async y await que vi en otros curso? cual seria el recomendable usar y porque

a

Hola, les dejo mi repositorio de este proyecto, pero hecho en Nextjs:

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