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

PWA: soporte offline

48/50
Recursos

Utilizaremos workbox-webpack-plugin para agregar soporte online a nuestro proyecto, así como lo hacen Twitter e Instagram cuando entramos desde el navegador.

Aportes 30

Preguntas 7

Ordenar por:

Los aportes, preguntas y respuestas son vitales para aprender en comunidad. Regístrate o inicia sesión para participar.

Podemos mejorar algunos aspectos del manifest.

    new WebpackPwaManifestPlugin({
      filename: 'manifest.webmanifest',
      name: 'IntaPlatzi',
      description: 'Tu app preferida para encontrar esas mascotas que tanto te encantan',
      orientation: 'portrait',
      display: 'standalone',
      start_url: '/',
      scope: '/',
      background_color: '#456BD9',
      theme_color: '#456BD9',
      icons: [
        {
          src: path.resolve(__dirname, 'src/assets/icon.png'),
          sizes: [96, 128, 192, 256, 384, 512],
          destination: path.join('Icons'),
          ios: true,
        },
      ],
    })```

Si tienen problemas para obtener con el audit que su app cumple los requisitos para ser una PWA, lo que deben hacer es ejecutar Chrome en modo incognito. Las extensiones bajan mucho el performance de la aplicacion

 new WorkboxPlugin.GenerateSW({
      swDest: 'service-worker.js',
      clientsClaim: true,
      skipWaiting: true,
      maximumFileSizeToCacheInBytes: 5000000,
      runtimeCaching: [
        {
          urlPattern: new RegExp(
            'https://(res.cloudinary.com|images.unsplash.com)'
          ),
          handler: 'CacheFirst',
          options: {
            cacheName: 'images'
          }
        },
        {
          urlPattern: new RegExp(
            'https://silnose-petgram-server-qjokcp6y2.vercel.app'
          ),
          handler: 'NetworkFirst',
          options: {
            cacheName: 'api'
          }
        }
      ]
    })

En mi caso no me funcionaba el modo offline y se rompia ya que no "cacheaba " el bundle js, en la consola donde tenia la app corriendo descubri este warning

WARNING in /app.bundle.js is 3.01 MB, and won’t be precached. Configure maximumFileSizeToCacheInBytes to change this limit.

y era ese el porque, mi app.bundle se esta conviertiendo en modo desarrollo y es pesado.

SOLUCION: En webpack en la configuracion de workbox agregue


{
  maximumFileSizeToCacheInBytes: 5000000,
  // ...other Workbox build configuration options...
}

FUENTE: https://stackoverflow.com/questions/46795409/how-to-cache-larger-files-for-development

NO OLVIDEN PONER EL PUNTITO ANTES DE LA BARRA ūüėĄ

public/index.html :

 if ('serviceWorker' in navigator) {
     window.addEventListener('load', () => {
       navigator.serviceWorker.register('./service-worker.js')// AQUI!!
        .then(registration => {
            console.log('SW registrado')
         })
        .catch(registrationError => {
            console.log('SW error '+ registrationError);
        })
    })
}

Este es mi resultado, la subí a firebase por que now no generaba bien el dist con las cosas de PWA.

Pettagram

Espero les guste y muchas gracias midudev por este cursaso, muy completo!

Bueno llegué hasta esta clase jaja no pude corregir este error, si alguien tiene la solucion se lo agradezco!

Este concepto de las PWAs es muy interesante ! es un plus del curso muy valioso.

Genial!! quiero el proyecto completo para repasarlo y no olvidar tanto aprendizaje. Gracias!!!

Porque no me aparece esa opcion de instalar en chrome? Tengo Ubutnu

Simplemente, Fantasticoooooo!!!

Wowowowow, incre√≠ble el resultado ūüėģ

Después de mucho rato sufriendo jajaja

  1. Utilic√© una p√°gina para generar el icono en los diferentes tama√Īos: https://www.simicart.com/manifest-generator.html/

  2. El webpack.config.js al final me qued√≥ as√≠ (organic√© los 4 tama√Īos que en todas las p√°ginas dec√≠an que era los importantes) y IMPORTANTE: agregar: purpose: 'any maskable', :

new WebpackPWAManifest({
      name: 'Petgram :)',
      short_name: 'Petgram',
      description: 'Encontrar fotos de mascotas',
      background_color: '#fff',
      theme_color: '#b1a',
      display: 'standalone',
      scope: '/',
      start_url: '/',
      icons: [
        {
          src: path.resolve('src/assets/icon-192x192.png'),
          size: '192x192',
          purpose: 'any maskable',
          type: 'image/png'
        },
        {
          src: path.resolve('src/assets/icon-256x256.png'),
          size: '256x256',
          purpose: 'any maskable',
          type: 'image/png'
        },
        {
          src: path.resolve('src/assets/icon-384x384.png'),
          size: '384x384',
          purpose: 'any maskable',
          type: 'image/png'
        },
        {
          src: path.resolve('src/assets/icon-512x512.png'),
          size: '512x512',
          purpose: 'any maskable',
          type: 'image/png'
        },
      ]      
    }), 

Y as√≠ POR FIN me dejo instalar jajaja no s√© si lo de los tama√Īos era necesario y con el purpose era suficiente pero bueno eso pru√©belo ustedes jajaja

![](

Tenía estos dos en rojo y los resolví de la siguiente manera
webpack.config.js - icons

	{
          src: path.resolve('src/assets/maskable-icon.png'),
          size: '1024x1024',
          purpose: 'maskable'
        },

index.js - head

<link rel="apple-touch-icon" href="/src/assets/icons/ios-icon.png" />

Detalle sobre las diferentes estrategias de carga

https://developers.google.com/web/tools/workbox/modules/workbox-strategies

curso donde se profundiza mas sobre SW && PWA ūüėÉ

https://platzi.com/clases/1313-pwa-react-js/12152-introduccion-a-workbox/

Me esta encantando este curso, es sin dudas el mal largo hasta ahora pero condensa muchos de los conocimientos que tenia sueltos. Me encantaria ver un curso que explique un poco mas a fondo como subir la app a un dominio y tenerla realmente disponible, ademas otra para native explicando lo que implica subir una app a la google play o la appStore.

Para los que tienen error en Manifest has maskable icon y les da bien en el installable o viceversa:
tenia problemas con poner un maskable icon porque me daba error el installable y si ponia un icono normal me daba error el Manifes has maskable icon.
Entonces entendí que icons: [ ... ] es un array de objetos y pueden poner otro icono.
Generé el maskable icon en: https://maskable.app/editor

      ...
         orientation: 'portrait',
         display: 'standalone',
         start_url: '/home',
         scope: '/',
         background_color: '#fff',
         theme_color: '#FC5500',
         icons: [
            {
               src: path.resolve(__dirname, 'src/assets/icon.png'),
               sizes: [96, 128, 192, 256, 384, 512],
               destination: path.join('Icons'),
               ios: true,
            },
            {
               src: path.resolve('src/assets/maskable_icon.png'),
               size: '1142x1142',
               purpose: 'maskable'
             },
         ]
      }),

En Nextjs usé next-offline, agregando la configuración del service worket en el next.config.js, que quedó así:

<code>
const withPWA = require('next-pwa');
const withOffline = require('next-offline');

const nextConfig = withPWA({
  pwa: {
    dest: 'public',
  },
  workboxOpts: {
    runtimeCaching: [
      {
        urlPattern: new RegExp('https://res.cloudinary.com|images.unsplash.com'),
        handler: 'CacheFirst',
        options: {
          cacheName: 'images',
        },
      },
      {
        urlPattern: new RegExp('https://petgram-server.now.sh'),
        handler: 'NetworkFirst',
        options: {
          cacheName:'api'
        },
      },
    ],
  },
});

module.exports = withOffline(nextConfig)

Tengo este problema aun terminando los dos √ļltimos v√≠deos me salen estos resultados

<
Aqui pueden ver

Cual es tu opinion de ServicesWorkers en IE11 ?.

Utilizaremos workbox-webpack-plugin para agregar soporte online a nuestro proyecto, así como lo hacen Twitter e Instagram cuando entramos desde el navegador.

Tengo un problema al colocar la opcion de Offline me aparece el error de que necesito javascript para usar la app. No entiendo

Recuerden que si no les da la calificación lo mas probable es por la extensiones de chrome, asi que mejor realicen la prueba desde incognito

Por qué no pudo cachear las categorías, si para solicitarlas se hace un request usando FETCH y no graphql?
Gracias Slds.

ūüėä

Estoy teniendo problemas para registrar el service worker en una Create react app, alguien puede revisar mi código plis?

https://github.com/behagoras/petgram/tree/serviceWorker

dejo el webpack.config.js que a día 17/04/2021 salió todo verde

const HtmlWebpackPlugin = require('html-webpack-plugin')
const WebpackPwaManifestPlugin = require('webpack-pwa-manifest')
const WorkboxWebpackPlugin = require('workbox-webpack-plugin')

const path = require('path')

module.exports = {
  output: {
    filename: 'app.bundle.js',
    publicPath: '/'
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: 'src/index.html'
    }),
    new WebpackPwaManifestPlugin({
      filename: 'manifest.webmanifest',
      name: 'IntaPlatzi',
      description: 'Tu app preferida para encontrar esas mascotas que tanto te encantan',
      orientation: 'portrait',
      display: 'standalone',
      start_url: '/',
      scope: '/',
      background_color: '#456BD9',
      theme_color: '#456BD9',
      prefer_related_applications: true,
      icons: [
        {
          src: path.resolve('src/assets/icon.png'),
          size: '1024x1024',
          sizes: [96, 128,144, 192, 256, 384, 512],
          purpose: 'maskable any',
          destination: path.join('Icons'),
          ios: true,
        }
      ]
    }),
    new WorkboxWebpackPlugin.GenerateSW({
      runtimeCaching: [
        {
          urlPattern: new RegExp('https://(res.cloudinary.com|images.unsplash.com)'),
          handler: 'CacheFirst',
          options: {
            cacheName: 'images'
          }
        },
        {
          urlPattern: new RegExp('https://petgram-server-tony-to-var-anthonytorresvargas.vercel.app'),
          handler: 'NetworkFirst',
          options: {
            cacheName: 'api'
          }
        }
      ]
    })
  ],
  devServer: {
    historyApiFallback: true
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env', '@babel/preset-react']
          }
        }
      }
    ]
  },
  resolve: {
    // ...
    alias: {
      // ...
      'react-dom$': 'react-dom/profiling',
      'scheduler/tracing': 'scheduler/tracing-profiling',
    },
    // ...
  },
}