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

Mostrar favoritos y solucionar fetch policy

40/50
Recursos

Aportes 28

Preguntas 7

Ordenar por:

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

o inicia sesi贸n.

con hooks

/* eslint-disable import/no-extraneous-dependencies */
import { useQuery } from '@apollo/react-hooks';
import qgl from 'graphql-tag';


const GET_FAVORITES = qgl`
query getFavs {
    favs {
      id
      categoryId
      src
      likes
      userId
    }
  }
`;


const useGetFavorites = () => {
  const { data, error, loading } = useQuery(GET_FAVORITES, { fetchPolicy: 'cache-and-network' });
  return { data, loading, error };
};


export default useGetFavorites;

fetchPolicy=鈥榗ache-and-network鈥 va a la red y obtiene una version fresca q almacena en el cache. Este es mejor por si hay acceso offline a la app.

import styled from 'styled-components'
import { Link as LinkRouter } from '@reach/router'

export const Link = styled(LinkRouter)`
    border-radius: 8px;
    box-shadow: 0 0 8px rgba(0,0,0,.3);
    display: inline-block;
    margin: 1%;
    overflow: hidden;
    position: relative;
    width: 31.33%;
    &:after {
        content: '';
        display: block;
        padding-bottom: 100%;
    }
`

export const Grid = styled.div`
    padding-top: 32px;
`

export const Image = styled.img`
    object-fit: cover;
    height: 100%;
    width: 100%;
    position: absolute;

Tengo un problema muy seguido me sale este error cuando entro a mi Favs page

Error GraphQL error: user does not exist

Sabran que sera?
Es como si se me borrara la base de datos de graphql 馃槖

26/04/2021 El codigo del video ya no funciona鈥 Dejo el c贸digo (que se que se puede mejorar pero hasta hoy funciona鈥) una vez acabado el video (Y) espero le sirva a alguien
GetFavorites:

import { useQuery, gql } from '@apollo/client'
import React from 'react'
import {ListOfFavs} from '../components/ListOfFavs'

const GET_FAVORITES = gql`
query getFavs {
    favs {
      id
      categoryId
      src
      likes
      userId
    }
  }
`;

const FavsWithQuery = () => {
    const { loading, data, error } = useQuery(GET_FAVORITES, {
        fetchPolicy: 'cache-and-network'
      })
      return { loading, data, error }
};

export const RenderProp = () => {
    const {loading, data, error} = FavsWithQuery();
    if(loading) return <p>Loading...</p>
    if(error) return <p>Error...</p>
    const {favs} = data

    return <ListOfFavs favs={favs} />

}

ListOfFavs y styles si funciona tal cual el video

Dejo mi aporte del uso de hooks para realizar el query GET_FAVS.

import { useQuery } from "@apollo/react-hooks";
import { gql } from "apollo-boost";

const GET_FAVS = gql`
  query getFavs {
    favs {
      id
      categoryId
      src
      likes
      userId
    }
  }
`;

export const useGetFavs = () => {
  const { data, loading, error } = useQuery(GET_FAVS, {
    fetchPolicy: "cache-and-network"
  });

  return { data, loading, error };
};

Hola chicos, intent茅 usar la nueva forma con hooks que han dejado en los comentarios, sin embargo, mi useQuery segu铆a sin traer los datos actualizados, as铆 que us茅 useEffect y extra铆 la propiedad refetch de useQuery

  const { loading, error, data, refetch } = useQuery(GET_FAVS_PHOTO)
  useEffect(() => refetch(), [])

B谩sicamente estoy diciendo que vuelva a hacer un fetch cada vez que el componente se renderice. Si quieren saber c贸mo funciona el refetch les dejo la documentaci贸n https://www.apollographql.com/docs/react/data/queries/#refetching

04/06/2022 (hooks, react-router-dom, @apollo/client)
src/hooks/useGetFavorite.js:

import { useQuery, gql } from '@apollo/client'

const GET_FAVORITES = gql`
    query getFavs {
        favs {
            id 
            categoryId
            src
            likes
            userId
        }
    }
`

export const useGetFavorite = ()=> {
    const {data, loading, error} = useQuery(GET_FAVORITES, {
        fetchPolicy: 'cache-and-network'
    })

    return {data , loading, error}
}

src/components/ListOfFavs/index.js:

import React from 'react';
import { Link, Grid, Image } from './styles';

export const ListOfFavs = ({ favs = [] })=> {
    return (
        <Grid>
            {
                favs.map(fav => (
                    <Link key={fav.id} to={`/detail/${fav.id}`} >
                        <Image src={fav.src} />
                    </Link>
                ))
            }
        </Grid>
    )
}

src/components/ListOfFavs/styles.js:

import styled from 'styled-components'
import { Link as LinkRouter } from 'react-router-dom'

export const Link = styled(LinkRouter)`
    position: relative;
    border-radius: 8px;
    box-shadow: 0 0 8px rgba(0,0,0,.3);
    display: inline-block;
    margin: 1%;
    overflow: hidden;
    width: 31.33%;
    &:after {
       content: "";
        display: block;
        padding-bottom: 100%;
    }
`

export const Grid = styled.div`
    padding-top: 32px;
`

export const Image = styled.img`
    object-fit: cover;
    height: 100%;
    width: 100%;
    position: absolute;
`

src/pages/Favs.js:

import React from 'react';
import { useGetFavorite } from '../hooks/useGetFavorite';
import { ListOfFavs } from '../components/ListOfFavs';

export const Favs = ()=> {
    const { data, loading, error } = useGetFavorite()

    if (loading) return 'loading...'
    if (error) return 'error'

    return <ListOfFavs favs={data.favs} />
}

Pensando en la reutilizacion de componentes, porque en lugar de crear un nuevo componente ListOfFavs que en esencia es lo mismo que el ListOfPhotoCards, no se modifica el componente (ListOfPhotoCards) para que reciba las fotos por props y se hace un hook en cada page (Home, Favs) para que obtenga las photos que se necesitan?

Creo que se esta haciendo doble trabajo.

Un aporte de como configurar el policy en los hooks

import { useQuery, gql } from '@apollo/client'
const GET_FAVS = gql`
query getFavs {
  favs {
    id
    categoryId
    src
    likes
    userId
  }
}
`
export const useGetFavorites = id => {
  const { loading, data, error } = useQuery(GET_FAVS, {
    fetchPolicy: 'network-only'
  })
  return { loading, data, error }
}

Como es que se le pasa el header de autenticaci贸n ??

como valida eso? automaticamente Apolo lo detecta?鈥

import { Query } from '@apollo/client/react/components'

El componente QUERY a fecha de hoy julio 2021 se encuentra en esa ruta鈥

As铆 me funcion贸 el GetFavorities.js al d铆a de hoy:

import { useQuery, gql } from '@apollo/client'
import React from 'react'
import { ListOfFavs } from '../components/ListOfFavs'

const GET_FAVORITES = gql`
  query getFavs {
    favs {
      id
      categoryId
      src
      likes
      userId
    }
  }
`

const RenderProp = ({ loading, data, error }) => {
  if (loading) return <p>Loading...</p>
  if (error) return <p>Error...</p>
  const { favs } = data

  return <ListOfFavs favs={favs} />
}

export const FavsWithQuery = () => {
  const { loading, error, data } = useQuery(GET_FAVORITES, {
    fetchPolicy: 'cache-and-network'
  })

  return <RenderProp loading={loading} data={data} error={error} />
}

Yo reus茅 el componente ListOfPhotoCard (yo lo llamo ListFeedCard) de la siguiente manera:
Nota: useGetFavorites() Es mi hook para obtener los datos, uso los hooks de GraphQl

export const FavsPage = () => {
  const { data, loading, error } = useGetFavorites()
  const [favs, setFavs] = useState([])

  useEffect(() => {
    if (data) setFavs(data.favs)
  }, [data])

  return <ListFeedCard list={favs} error={error} loading={loading} />
}

Me esta encantando este curso, super super completo, con detalles en los errores y posibles errores! Muy contento de haberlo iniciado!

Hola Chicos, vengo del futuro y Les dejo una mejora en PhotoCardWithQuery.js para evitar pasar data empty al renderizar PhotoCard:

const renderProp = ({ loading, error, data = { photo: {} } }) => {
//   if (loading) return <p>Loading... </p>
  if (error) return <p>Error!</p>
  if (data) {
    const { photo = {} } = data
    if (Object.keys(photo).length) {
      return <PhotoCard {...photo} loading={loading} />
    }
  }
  return null
}```

Esto les ayudara mas adelante cuando vean validaciones dentro de los proptypes.
Saludos 馃惐鈥嶐煆

Yo realiza el codigo utilizando hooks:

import { gql, useQuery } from '@apollo/client';

const GET_FAVORITES = gql`
query getFavs{
  favs{
    id
    categoryId
    src
    likes
    userId
  }
}
`;

export const useGetFavPhotos = ()=>{
  const { loading, data, error } = useQuery(GET_FAVORITES,{
    fetchPolicy: 'cache-and-network'
  });
  return { loading, data, error }
}

import React from "react"
import { ListOfFavs } from "../components/ListOfFavs"
import { useGetFavPhotos } from "../hooks/useGetFavPhotos";

export const Favs = ()=>{
  const { loading, data, error } = useGetFavPhotos();
  if(loading) return <p>Loading...</p>
  if(error)   return <p>Error...</p>
  const {favs} = data;
  return (
    <>
      <ListOfFavs favs={favs} />
    </>
  )
}

import React from 'react'
import { Grid, Image, Link } from './styles'

export const ListOfFavs = ({favs = []})=>{
  return (
    <Grid>
      {
        favs.map(fav=>(
          <Link  key={fav.id} to={`/detail/${fav.id}`} >
            <Image src={fav.src} />
          </Link>
        ))
      }
    </Grid>
  )
}

import styled from 'styled-components'
import { Link as LinkRouter } from 'react-router-dom'

export const Link = styled(LinkRouter)`
  border-radius: 8px;
  box-shadow: 0 0 8px rgba(0,0,0,.3);
  display: inline-block;
  margin: 1%;
  overflow: hidden;
  position: relative;
  width: 31.33%;
  &:after{
    content:'';
    display: block;
    padding-bottom: 100%;
  }
`

export const Grid = styled.div`
  padding-top: 32px;
`

export const Image = styled.img`
  object-fit: cover;
  height: 100%;
  width: 100%;
  position: absolute;
`

Hola a todos, estoy en 05/04/2022
Ya no hay ese problema de cache, entiendo que por esta parte del codigo:

const client = new ApolloClient({
  ...
  cache: new InMemoryCache(),
  ...
})

En cuanto al codigo utiliado, emplee hooks:
hooks/useGetFavs

import React from 'react'
import { ListOfFavs } from '../components/ListOfFavs';
import { useQuery, gql } from '@apollo/client';

const GET_FAVORITES = gql`
  query getFavs {
    favs {
      id
      categoryId
      src
      likes
      userId
    }
  }
`;

const FavsWithQuery = () => {
  const { loading, data, error } = useQuery(GET_FAVORITES, {
      fetchPolicy: 'cache-and-network'
  })
  return { loading, data, error }
};

export const RenderProp = () => {
  const {loading, data, error} = FavsWithQuery();
  if(loading) return <p>Loading...</p>
  if(error)   return <p>Error...</p>
  const {favs} = data
  return <ListOfFavs favs={favs} />
}

pages/Favs

import React from 'react'
import { RenderProp } from '../hooks/useGetFavs'

export const Favs = ()=>(
  <>
    <h1>Favs</h1>
    <RenderProp />
  </>
)

components/ListOfFavs:

import React from 'react'
import { Grid, Image, Link } from './styles'

export const ListOfFavs = ({favs = []})=>{
  return (
    <Grid>
      {
        favs.map(fav=>(
          <Link  key={fav.id} to={`/detail/${fav.id}`} >
            <Image src={fav.src} />
          </Link>
        ))
      }
    </Grid>
  )
}

components/ListOfFavs/styles

import styled from 'styled-components'
import { Link as LinkRouter } from 'react-router-dom'

export const Link = styled(LinkRouter)`
  border-radius: 8px;
  box-shadow: 0 0 8px rgba(0,0,0,.3);
  display: inline-block;
  margin: 1%;
  overflow: hidden;
  position: relative;
  width: 31.33%;
  &:after{
    content:'';
    display: block;
    padding-bottom: 100%;
  }
`

export const Grid = styled.div`
  padding-top: 32px;
`

export const Image = styled.img`
  object-fit: cover;
  height: 100%;
  width: 100%;
  position: absolute;
`

Exitos camaradas

Hola, les dejo el avance de mi proyecto hecho en Nextjs:

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

Hola Devs:
-Aqui les traigo un aporte, les comparto este articulo que habla bien sobre el fetchPolicy, espero que les ayude a entender mejor y sacarle el maximo provecho: Click Aqui

Excelente!!

驴Se podr铆a guardar los favoritos sin que se tenga que registrar?

Excelente

Esta solucion me parecio la mejor con hooks https://www.apollographql.com/docs/react/data/queries/#refetching

genial!!