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!

A√ļn no tienes acceso a esta clase

Crea una cuenta y contin√ļa viendo este curso

Curso de React Avanzado

Curso de React Avanzado

Miguel √Āngel Dur√°n

Miguel √Āngel Dur√°n

Refactorizando y usando variables de loading y error

24/50
Recursos

Aportes 16

Preguntas 3

Ordenar por:

¬ŅQuieres ver m√°s aportes, preguntas y respuestas de la comunidad? Crea una cuenta o inicia sesi√≥n.

Me paso algo curioso, mi internet va lentisimo(estoy en Venezuela) por lo cual si no usaba la variable loading para indicar que estaba cargando la data, siempre me devolvia error, ya que la data nunca llego a definirse, me decia que no podia leer photos de undefined; la solucion era muy sencilla (tonto yo que no se me ocurrio desde un principio) y justamente la saque de la web de midudev (nuestro profesor jajajaja) donde el explica a fondo como usar graphql, tendria que haber saltado a este video desde un principio,

Les dejo mi código para los que quieran hacer un efecto de Placeholder loading

deben instalar esta dependencia

recuerden pasarle la propiedad ‚Äúloading‚ÄĚ al PhotoCard

...
import ReactPlaceholder from "react-placeholder"
import { TextBlock, RectShape, RoundShape } from "react-placeholder/lib/placeholders"

...

  const photoCardSkeleton = (
    <React.Fragment>
      <RectShape color="#eee" style={{ height: "400px", marginBottom: 10 }} />
      <div style={{ display: "flex", flexDirection: "row", alignItems: "center" }}>
        <RoundShape
          color="#eee"
          style={{ width: 50, height: 50, marginLeft: 10, marginRight: 10 }}
        />
        <TextBlock color="#eee" rows={1} style={{ width: 120 }} />
      </div>
    </React.Fragment>
  )

return (
    <Article ref={element}>
      {show && (
        <ReactPlaceholder
          ready={!loading}
          showLoadingAnimation={true}
          customPlaceholder={photoCardSkeleton}
        >
          <React.Fragment>
            <a href={`/?detail=${id}`}>
              <ImgWrapper>
                <Img src={src} />
              </ImgWrapper>
            </a>
            <Button onClick={() => setLiked(!liked)}>
              <Icon size="32px" /> {likes} likes!
            </Button>
          </React.Fragment>
        </ReactPlaceholder>
      )}
    </Article>
  )

quedaría así:

‚ÄúVer comentario anterior para el c√≥digo‚ÄĚ

El componente quedaría así

Prueben mi componente loader para las photos

Componente

import React from 'react'
import { Loader } from '../../components/PhotoLoader/styles'

export const PhotoLoader = () => {
  return (
    <Loader />
  )
}

Estilo

import styled from 'styled-components'
import { skeletonAnimation } from '../../styles/animation'

export const Loader = styled.div`
  padding: 150px;
  color: #f6f7f8;
  background: #f6f7f8;
  margin: 10px;
  box-shadow: 0px 10px 14px rgba(0, 0, 0, 0.2);
  border-radius: 6px;
  overflow: hidden;
  height: auto;
  width: 414px;
  ${skeletonAnimation}
`

Animación

const placeHolderShimmer = keyframes`
    0%{
        background-position: -490px 0
    }
    100%{
        background-position: 490px 0
    }
`
export const skeletonAnimation = ({
  time = '1s',
  fill = 'forwards',
  iteration = 'infinite',
  timingFunction = 'linear',
  colorBackground = '#f6f7f8',
  colorAnimation = '#edeef1'
} = {}) =>
  css`
    animation-duration: ${time};
    animation-fill-mode: ${fill};
    animation-iteration-count: ${iteration};
    animation-name: ${placeHolderShimmer};
    animation-timing-function: ${timingFunction};
    background-image: -webkit-gradient(
      linear,
      left center,
      right center,
      from(${colorBackground}),
      color-stop(0.2, ${colorAnimation}),
      color-stop(0.4, ${colorAnimation}),
      to(${colorBackground})
    );
    background-image: -webkit-linear-gradient(
      left,
      ${colorBackground} 0%,
      ${colorAnimation} 20%,
      ${colorBackground} 40%,
      ${colorBackground} 100%
    );
    position: relative;
  `

Si quieren ver mas tiempo el loader, en la consola vayan a network y seleccionen slow 3g

Para cargar un loader mientras carga la foto tendrian que modificar la función renderProps y retornar un styled component con el loader de la siguiente forma:

 const renderProps = ({ loading, error, data: { photo = {} } }) => {
  if (loading) return <Loader />
  if (error) return `Error! ${error.message}`
  return <PhotoCard {...photo} />
}```

Cree un nuevo componente para cuando este cargando y lo agregué en la carpeta de PhotoCard. Use el mismo archivo para estilos ya que solo use dos etiquetas;)

styled-components

les comparto el skeleton que hice adaptando con styled-components

import React from 'react';
import { SkeletonImg, SkeletonInfo, SkeletonItem, SkeletonName } from '../shared/Skeleton';

const Skeleton = () => {
  return (
    <SkeletonItem>
      <div>
        <SkeletonImg></SkeletonImg>
      </div>
      <SkeletonInfo>
        <SkeletonName />
        <SkeletonName />
      </SkeletonInfo>
    </SkeletonItem>
  );
};

export default Skeleton;

Aquí los estilos:

import styled, { css, keyframes } from "styled-components"

const loading = keyframes`
  0% {
    transform: translateX(0);
  }
  100% {
    transform: translateX(460px);
  }
}
`
export const SkeletonItem = styled.li`
  background-color: rgb(218, 218, 218);
  display: flex;
  align-items: center;
  margin: 15px 0;
  padding: 20px;
  border: 1px solid #ccc;
  border-radius: 4px;
  position: relative;
`

export const SkeletonImg = styled.div`
  width: 50px;
  height: 50px;
  border-radius: 50%;
  background: #f2f2f2;
  position: relative;
  overflow: hidden;
  &::before {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    width: 30px;
    height: 100%;
    background: linear-gradient(to right, #f2f2f2, #ddd, #f2f2f2);
    animation: ${loading} 2s infinite linear;
  }
`

export const SkeletonInfo = styled.div`
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  margin-left: 10px;
`

export const SkeletonName = styled.div`
  width: 70%;
  height: 18px;
  background: #f2f2f2;
  position: relative;
  overflow: hidden;
  &::before {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    width: 30px;
    height: 100%;
    background: linear-gradient(to right, #f2f2f2, #ddd, #f2f2f2);
    animation: ${loading} 2s infinite linear;
  }
`

https://loading.io/ por si quieren un loading

Lo de la separación de código se aprecia como buena práctica. ya que es un desarrollo compartido

skeleton para el loading y toast para el mensaje de error,

Nos pasamos el curso refactorizando

n

Genial!!!