esto debería tener un video !!!
¡Bienvenida! Este es un curso especial de React Hooks
¿Qué aprenderás en el Curso Profesional de React Hooks?
¿Qué son los React Hooks y cómo cambian el desarrollo con React?
Introducción a React Hooks
useState: estado en componentes creados como funciones
useEffect: olvida el ciclo de vida, ahora piensa en efectos
useContext: la fusión de React Hooks y React Context
useReducer: como useState, pero más escalable
¿Qué es memoization? Programación funcional en JavaScript
useMemo: evita cálculos innecesarios en componentes
useRef: manejo profesional de inputs y formularios
useCallback: evita cálculos innecesarios en funciones
Optimización de componentes en React con React.memo
Custom hooks: abstracción en la lógica de tus componentes
Third Party Custom Hooks de Redux y React Router
Configura un entorno de desarrollo profesional
Proyecto: análisis y retos de Platzi Conf Store
Instalación de Webpack y Babel: presets, plugins y loaders
Configuración de Webpack 5 y webpack-dev-server
Configuración de Webpack 5 con loaders y estilos
Loaders de Webpack para Preprocesadores CSS
Flujo de desarrollo seguro y consistente con ESLint y Prettier
Git Hooks con Husky
Estructura y creación de componentes para Platzi Conf Store
Arquitectura de vistas y componentes con React Router DOM
Maquetación y estilos del home
Maquetación y estilos de la lista de productos
Maquetación y estilos del formulario de checkout
Maquetación y estilos de la información del usuario
Maquetación y estilos del flujo de pago
Integración de íconos y conexión con React Router
Integración de React Hooks en Platzi Conf Merch
Creando nuestro primer custom hook
Implementando useContext en Platzi Conf Merch
useContext en la página de checkout
useRef en la página de checkout
Integrando third party custom hooks en Platzi Conf Merch
Configura mapas y pagos con PayPal y Google Maps
Paso a paso para conectar tu aplicación con la API de PayPal
Integración de pagos con la API de PayPal
Completando la integración de pagos con la API de PayPal
Paso a paso para conectar tu aplicación con la API de Google Maps
Integración de Google Maps en el mapa de checkout
Creando un Custom Hook para Google Maps
Estrategias de deployment profesional
Continuous integration y continuous delivery con GitHub Actions
Compra del dominio y despliega con Cloudflare
Optimización de aplicaciones web con React
Integración de React Helmet para mejorar el SEO con meta etiquetas
Análisis de performance con Google Lighthouse
Convierte tu aplicación de React en PWA
Bonus: trabaja con Strapi CMS para crear tu propia API
Crea una API con Strapi CMS y consúmela con React.js
¿Qué sigue en tu carrera profesional?
Próximos pasos para especializarte en frontend
Lectura
Lo primero que tenemos que crear es nuestro service-worker.js dentro de la carpeta /public:
const doCache = false;
const CACHE_NAME = 'pwa-cache';
self.addEventListener("activate", event => {
const cacheWhitelist = [CACHE_NAME];
event.waitUntil(
caches.keys()
.then(keyList =>
Promise.all(keyList.map(key => {
if (!cacheWhitelist.includes(key)) {
console.log(`Deleting cache: ${key}`)
return caches.delete(key);
}
}))
)
);
});
self.addEventListener('install', function (event) {
if (doCache) {
event.waitUntil(
caches.open(CACHE_NAME)
.then(function (cache) {
fetch("manifest.json")
.then(response => {
response.json()
})
.then(assets => {
const urlsToCache = [
"/",
assets["bundle.js"]
]
cache.addAll(urlsToCache)
console.log('cached');
})
})
);
}
});
self.addEventListener('fetch', function (event) {
if (doCache) {
event.respondWith(
caches.match(event.request).then(function (response) {
return response || fetch(event.request);
})
);
}
});
La configuración previa nos permite registrar nuestra aplicación debidamente. Ahora vamos a crear el archivo de configuración donde podremos agregar el nombre de nuestra aplicación, ícono entre otras características importantes que describen la aplicación.
Crear el archivo manifest.json en la carpeta /public:
{
"short_name": "Platzi Conf Store",
"name": "A simple Store",
"icons": [
{
"src": "assets/icon.png",
"sizes": "512x512",
"type": "image/png"
}
],
"start_url": "/",
"background_color": "#222",
"theme_color": "#222",
"display": "standalone"
}
Descarga el ícono de React de la sección de recursos y agrégalo a la carpeta /public.
Para continuar con el proceso de la construcción de la PWA es necesario instalar un plugin para webpack que nos ayudará a copiar los archivos de la carpeta /public a la carpeta de nuestro proyecto compilado.
npm install copy-webpack-plugin --save-dev
Una vez instalado, es necesario agregar la configuración necesaria en el archivo wepack.config.js
Primero importamos copy-webpack-plugin en la parte superior del archivo
const CopyPlugin = require('copy-webpack-plugin');
Agregamos la configuración necesaria en la sección de plugins:
new CopyPlugin({
patterns: [
{ from: 'public/manifest.json', to: '' },
{ from: 'public/service-worker.js', to: '' },
{ from: 'public/icon.png', to: 'assets' },
],
}),
En este caso estamos agregando 3 elementos a la carpeta dist, el primero es nuestro archivo manifest, luego agrega el archivo service-worker.js y al final el archivo icon.png, de esta forma al compilar el proyecto podemos disponer de estos archivos dentro del compilado final.
Una de las tareas que tenemos que realizar antes de probar nuestra aplicación es agregar el soporte del service worker al proyecto creando la lógica siguiente dentro de index.html.
<script>
if ('serviceWorker' in navigator) {
window.addEventListener('load', function () {
navigator.serviceWorker.register('service-worker.js').then(function (registration) {
console.log('ServiceWorker registration successful with scope: ', registration.scope);
}, function (err) {
console.log('ServiceWorker registration failed: ', err);
}).catch(function (err) {
console.log(err)
});
});
} else {
console.log('service worker is not supported');
}
</script>
Ahora demos de agregar la referencia al archivo manifest.json dentro de la etiqueta <head>:
<link rel="manifest" href="/manifest.json">
Una vez agregado el script y la referencia al manifest dentro del archivo index.html procedemos a compilar el proyecto:
npm run build
Cuando termina el proceso podemos revisar la carpeta /dist que ha generado Webpack y revisar que tenemos dentro el archivo manifest.json así como el archivo service-worker.js y dentro de assets el ícono que vamos a utilizar.
Ahora podemos correr el proyecto y comprobar que tenemos el registro del service worker y la información de nuestra aplicación:
npm run start
Service worker registrado correctamente:
Registro del manifest dentro de la aplicación:
Ahora puedes instalar Platzi Conf Store en tu computadora y aprovechar las ventajas de utilizar una PWA:
Si quieres aprender más acerca de convertir tus aplicaciones de React en rápidas aplicaciones te recomiendo el curso Curso de Progressive Web Apps con React.js.
Aportes 19
Preguntas 4
esto debería tener un video !!!
Acá les dejo el service-worker.js corregido por ESLint:
const doCache = false;
const CACHE_NAME = 'pwa-cache';
self.addEventListener("activate", event => {
const cacheWhitelist = [CACHE_NAME];
event.waitUntil(
caches.keys()
.then(keyList =>
Promise.all(keyList.map(key => {
if (!cacheWhitelist.includes(key)) {
console.log(`Deleting cache: ${key}`)
return caches.delete(key);
}
}))
)
);
});
self.addEventListener('install', (event) => {
if (doCache) {
event.waitUntil(
caches.open(CACHE_NAME)
.then((cache) => {
fetch("manifest.json")
.then(response => {
response.json()
})
.then(assets => {
const urlsToCache = [
"/",
assets["bundle.js"]
]
cache.addAll(urlsToCache)
console.log('cached');
})
})
);
}
});
self.addEventListener('fetch', (event) => {
if (doCache) {
event.respondWith(
caches.match(event.request).then((response) => {
return response || fetch(event.request);
})
);
}
});
En mi caso me generaba error al compilar, y lo que me funciono fue cambiar <link rel=“manifest” href="/manifest.json"> por <link rel=“manifest” href="./manifest.json"> . De esa manera si me funciono.Ademas el icono lo tenia de 50x50 y tuve que cambiarlo por 512x512.
En Nextjs se pueden usar complementos para generar la configuración de la PWA, tales como next-pwa o next-offline. Sin embargo, si uno quisiera hacer la configuración desde 0, desde la versión 9.1 de NextJS tenemos la carpeta “public”, en donde podemos agregar sin problema el service-worker.js y el manifest.json.
Lo único diferente que tuve que hacer, fue en el archivo _app.js, agregué un useEffect para cargar el eventlistener y lel componente Head para la referencia al manifest:
function MyApp({ Component, pageProps }) {
const initialState = useInitialState();
useEffect(() => {
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker
.register('/service-worker.js')
.then(
(registration)=> {
console.log(
'ServiceWorker registration successful with scope: ',
registration.scope
);
},
(err) =>{
console.log('ServiceWorker registration failed: ', err);
}
)
.catch((err) =>{
console.log(err);
});
});
} else {
console.log('service worker is not supported');
}
}, []);
return (
<>
<Head>
<link rel="manifest" href="/manifest.json" />
</Head>
<AppContext.Provider value={initialState}>
<Component {...pageProps} />
</AppContext.Provider>
</>
);
}
Con esta configuración aún no llego al 100% en PWA, pero el resultado es bastante bueno:
https://imgur.com/sWpuBkQ

Les dejo los links de next-offline y next-pwa:
https://www.npmjs.com/package/next-offline
https://www.npmjs.com/package/next-pwa?activeTab=readme
Adicionalmente, pueden ver mi proyecto del curso de React avanzado, que lo hice con Nextjs y lo convertí en una PWA usando ambas herramientas. Les dejo el link del repositorio:
https://github.com/danyel117/petgram-platzi
Les dejo el enlace al ícono de Platzi
Me sale este error, alguien sabe porqué?
Tuve un error al generar el service-worker que hacía que el registro fallara porque el js era incorrecto, lo solucioné reemplazando los saltos de línea del archivo service-worker.js por saltos de línea de mi teclado. Esto se debe a que al hacer copy&paste de ese código se ingresan unos caracteres inválidos para el navegador.
Donde esta el icono de react? Dice que en la sección de recursos pero donde está esa sección en un artículo como este? Ya tambien busque en otras clases y no lo encuentro…
No me reconocía el service-worker.js y me daba error, lo que pasó es que cuando copié y pegué la configuracion del archivo de service-worker.js tenia un formato raro o invalido en los saltos de línea, lo que hice fue borrar cada salto de línea y hacer el salto de línea yo mismo con “enter” y me funcionó, que alivio…
Excelente claro que mirare el curso e PWA pronto
Actualicen el texto donde mencionan descargar el icono de react, porque confunde.
Excelente, esta clase ademas se complementa con el curso de webpack
Debería ser un video o al menos explicar que es una PWA y porque es importante convertir la aplicación a una. La verdad este curso me ha parecido muy deficiente a comparación de otros. Y está desactualizado al 2022
No se si a alguien más le pasó, pero me saltaba un error por que no encontraba el archivo manifest.json
ERROR in Error: Child compilation failed:
Module not found: Error: Can't resolve '/manifest.json'
Solo tienen que cambiar en el index.html el link del manifest, agregen un punto atras del /:
<link rel="manifest" href="./manifest.json">
Excelente claro, Si funciono este curso de PWA
en el Curso de React Avanzado se explica una forma más sencilla de convertir a PWA, mediante plugins de Webpack podemos hacer estas configuraciones más fácilmente (el manifest y el service worker). Les recomiendo el curso entero porque es genial pero de una vez dejo las clases sobre PWA:
Que raro en Firefox no me sale el icon pero si en google. Puede ser por las dimensiones del icono?
Acá les dejo el service-worker.js corregido por ESLint:
´´´
const doCache = false;
const CACHE_NAME = ‘pwa-cache’;
self.addEventListener(“activate”, event => {
const cacheWhitelist = [CACHE_NAME];
event.waitUntil(
caches.keys()
.then(keyList =>
Promise.all(keyList.map(key => {
if (!cacheWhitelist.includes(key)) {
console.log(Deleting cache: ${key}
)
return caches.delete(key);
}
}))
)
);
});
self.addEventListener(‘install’, (event) => {
if (doCache) {
event.waitUntil(
caches.open(CACHE_NAME)
.then((cache) => {
fetch(“manifest.json”)
.then(response => {
response.json()
})
.then(assets => {
const urlsToCache = [
"/",
assets[“bundle.js”]
]
cache.addAll(urlsToCache)
console.log(‘cached’);
})
})
);
}
});
self.addEventListener(‘fetch’, (event) => {
if (doCache) {
event.respondWith(
caches.match(event.request).then((response) => {
return response || fetch(event.request);
})
);
}
});
´´´
Super, gracias!
Los aportes, preguntas y respuestas son vitales para aprender en comunidad. Regístrate o inicia sesión para participar.