Una acotación importante es que React.lazy y Suspense solo funcionan en Client Side Rendering. Si su aplicación usa Server Side Rendering deberán usar loadable-components https://reactjs.org/docs/code-splitting.html#reactlazy
Introducción al curso avanzado de React
Qué necesitas para este curso y qué aprenderás sobre React.js
Proyecto y tecnologías que usaremos
Preparando el entorno de desarrollo
Clonando el repositorio e instalando Webpack
Instalación de React y Babel
Zeit es ahora Vercel
Linter, extensiones y deploy con Now
Creando la interfaz con styled-components
¿Qué es CSS-in-JS?
Creando nuestro primer componente: Category
Creando ListOfCategories y estilos globales
Usar información real de las categorías
Creando PhotoCard y usando react-icon
SVGR: de SVG a componente de ReactJS
Creando animaciones con keyframes
Hooks
¿Qué son los Hooks?
useEffect: limpiando eventos
useCategoriesData
Usando Intersection Observer
Uso de polyfill de Intersection Observer e imports dinámicos
Usando el localStorage para guardar los likes
Custom Hooks: useNearScreen y useLocalStorage
GraphQL y React Apollo
¿Qué es GraphQL y React Apollo? Inicializando React Apollo Client y primer HoC
Parámetros para un query con GraphQL
Usar render Props para recuperar una foto
Refactorizando y usando variables de loading y error
Usando las mutaciones con los likes
Reach Router
¿Qué es Reach Router? Creando la ruta Home
Usando Link para evitar recargar la página
Creando la página Detail
Agregando un NavBar a nuestra app
Estilando las páginas activas
Rutas protegidas
Gestión del usuario
Introducción a React.Context
Creación del componente UserForm; y Hook useInputValue
Estilando el formulario
Mutaciones para registro
Controlar estado de carga y error al registrar un usuario
Mutaciones para iniciar sesión
Persistiendo datos en Session Storage
Hacer like como usuario registrado
Mostrar favoritos y solucionar fetch policy
Cerrar sesión
Mejores prácticas, SEO y recomendaciones
Últimos retoques a las rutas de nuestra aplicación
React Helmet
Midiendo el performance de nuestra app y usando React.memo()
React.lazy() y componente Suspense
Usando PropTypes para validar las props
PWA: generando el manifest
PWA: soporte offline
Testing con Cypress
Conclusiones
¡Felicidades!
No tienes acceso a esta clase
¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera
Suspense es un componente de React que nos va a permitir suspender algo cuando está en modo lazy()
; y lazy()
. El cual nos va a permitir importar un componente que no será cargado hasta que este sea llamado. De esta forma mejoraremos el tiempo de carga de nuestra aplicación enormemente.
Aportes 19
Preguntas 0
Una acotación importante es que React.lazy y Suspense solo funcionan en Client Side Rendering. Si su aplicación usa Server Side Rendering deberán usar loadable-components https://reactjs.org/docs/code-splitting.html#reactlazy
Por si quieren utilizar React.lazy() en el resto de páginas:
const Home = React.lazy(() => import('./pages/Home'))
const Detail = React.lazy(() => import('./pages/Detail'))
const Favs = React.lazy(() => import('./pages/Favs'))
const User = React.lazy(() => import('./pages/User'))
const NotRegisteredUser = React.lazy(() => import('./pages/NotRegisteredUser'))
const NotFound = React.lazy(() => import('./pages/NotFound'))
Recuerden poner export default en los archivos de las páginas para que funcione!
En Suspense el fallback lo podemos utilizar como el componente que vamos a renderizar envés del componente deseado mientras hacemos la carga, para ésto podemos crear un componente, digamos <Spinner />
.
El Suspense quedaría así:
import React, {Suspense} from 'react'
import Spinner from './components/Spinner';
export const App = () => (
return <Suspense fallback={<Spinner />}>
// Code
</Suspense>)
Un pequeño aporte, para importar un componente de manera nombrada en React.lazy, se puede hacer de estar forma.
const Favs = React.lazy(() => import('./pages/Favs').then(module => ({ default: module.Favs })))
Asi ya no tendras que cambiar la page Favs
En el fallback acepta cualquier componente de react y este aparecerá hasta que el componente en suspenso sea cargado.
Podríamos hacer que mientras este componente cargue sea mostrado el Loader animation que fue hecho en clases pasadas de esta forma y asi aumentar el UX:
import { Loader } from './styles/animations'
<Suspense fallback={<Loader />}>```
Aconsejo correr lighthouse para medir la performance de la app. Esta herramienta de dice cuales son los mayores pains y como solucionarlos.
.
Para medir realmente la performance de la web se tiene que hacer en el entorno de produccion porq react agrega muchas alertas y demas cosas que ayudan en desarrollo pero que no aportan en prod 😅
.
Hice un test de performance en dev y dio 28 de 100, y en prod dio 89 de 100.
.
Para correr el ambiente de prod solo agregue un script mmas en el package.json
"serve:prod": "webpack --mode 'production' && npx serve dist -s",
Tambien dejo la doc oficial de react sobre el tema que esta super completa!
.
Espero que les sirva 😄
App.js
import React, {useContext, Suspense} from "react";
import { BrowserRouter, Routes, Route, Navigate} from "react-router-dom";
import { AppContext } from "./Context/AppContext";
//styles
import { GlobalStyle } from "./Styles/GlobalStyles";
//PAGES
import { Home } from './Pages/Home';
import { Detail } from "./Pages/Detail";
// import { Favs } from "./Pages/Favs";
import { User } from "./Pages/User";
import { NotRegisteredUser } from "./Pages/NotRegisteredUser";
import { NotFound } from "./Pages/NotFound";
//COMPONENTS
import { Logo } from './Components/Logo';
import { NavBar } from './Components/NavBar';
const Favs = React.lazy(() => import ('./Pages/Favs'))
export const App = () =>{
// const urlParams = new window.URLSearchParams(window.location.search)
// const detailId = urlParams.get('detail')
// console.log(detailId)
const { isAuth } = useContext(AppContext)
return (
<Suspense fallback={<div />}>
<BrowserRouter>
<GlobalStyle />
<Logo />
<Routes>
<Route exact path='/' element={<Home />} />
<Route exact path='/pet/:id' element={<Home />} />
<Route exact path='/detail/:id' element={<Detail />} />
<Route exact path='/favs' element={isAuth ? <Favs /> : <Navigate replace to='/login' />}/>
<Route exact path='/user' element={isAuth ? <User /> : <Navigate replace to='/login' />} />
<Route exact path='/login' element={!isAuth ? <NotRegisteredUser /> : <Navigate replace to='/' />} />
<Route path='*' element={<NotFound />} />
</Routes>
<NavBar />
</BrowserRouter>
</Suspense>
)
}
Favs.js
import React from 'react';
import { Layout } from '../Components/Layout';
import { FavsWithQuery } from '../Container/GetFavorites';
export default () => {
return (
<Layout title= 'Your favorites' subtitle='Your favorites images'>
<FavsWithQuery />
</Layout>
)
}
Si en algun momento react lazy les da error, prueben a ver si tienen la version 17 de react, si es asi hagan el downgrade con npm i [email protected] , al parecer aun de momento no funciona en esa version, al menos a mi.
Alguien sabe por qué de esto?
)
Dejo mis apuntes de esta clase por si alguien mas le sirven (los hice en notion), los pueden duplicar como un template
Como dato para algunos, tal vez un poco obvio… Pero tengan en cuenta que si crearon como en mi caso un skeleton… y quieren usar el lazy, esto cambiaria la funcionalidad por lo que tendrian que crear un super skeleton de toda la app (Pagina)… para mostrar mientras se carga
Muy buena esta practica ademas que podemos mejorar UX pasandole un componente en fallback aqui mis apuntes 😃
Suspense es un componente de React que nos va a permitir suspender algo cuando está en modo lazy(); y lazy(). El cual nos va a permitir importar un componente que no será cargado hasta que este sea llamado. De esta forma mejoraremos el tiempo de carga de nuestra aplicación enormemente.
Paso 1: implementar el lazy para que se importe solo ese componente cuando se va a renderizar
const Favs = React.lazy(() => import(’./pages/Favs’))
Paso 2: Exportar el componente como export default
Paso 3: Importar suspense de React y envolver a toda la app pasandole un fallback que acepta cualquier componente de react y este aparecerá hasta que el componente en suspenso sea cargado.
Suspense fallback={<div />}
Suspense es un componente de React que nos va a permitir suspender algo cuando está en modo lazy(); y lazy(). El cual nos va a permitir importar un componente que no será cargado hasta que este sea llamado. De esta forma mejoraremos el tiempo de carga de nuestra aplicación enormemente.
Según tengo entendido Suspense sigue en beta, o ¿ya fue lanzado de manera oficial?
Supongo que una aplicación de React no puede estar completa si no se usa Lazy, podríamos decir que es algo esencial o hay quienes prefieren no usarlo?
Porqué mi app.bundle pesa 3 MB y el del profe 181B ??
algo tengo que mover en webpack?
App.js con algunas páginas extra importadas dinámicamente:
import React, { Fragment, useContext, Suspense } from 'react'
import { GlobalStyle } from './styles/GlobalStyles'
import {Logo} from './components/Logo'
import {Home} from './pages/Home'
import {Redirect, Router} from '@reach/router'
// import {Detail} from './pages/Detail'
// import {Favs} from './pages/Favs'
// import {User} from './pages/User'
// import {NotRegisteredUser} from './pages/NotRegisteredUser'
import {NavBar} from './components/NavBar'
import {Context} from './Context'
// import {NotFound} from './pages/NotFound'
const Favs = React.lazy(() => import ('./pages/Favs'))
const Detail = React.lazy(() => import ('./pages/Detail'))
const User = React.lazy(() => import ('./pages/User'))
const NotRegisteredUser = React.lazy(() => import ('./pages/NotRegisteredUser'))
const NotFound = React.lazy(() => import ('./pages/NotFound'))
export const App = () => {
const {isAuth} = useContext(Context)
return (
<Suspense fallback={<div/>}>
<Logo />
<GlobalStyle />
<Router>
<NotFound default />
<Home path="/" />
<Home path="/pet/:categoryId" />
<Detail path="/detail/:detailId" />
{!isAuth && <NotRegisteredUser path='/login' />}
{!isAuth && <Redirect noThrow from='/favs' to='/login' />}
{!isAuth && <Redirect noThrow from='/user' to='/login' />}
{isAuth && <Redirect noThrow from='/login' to='/'/>}
<Favs path="/favs" />
<User path="/user" />
</Router>
<NavBar />
</Suspense>
)
}
y en todas esas páginas se cambia por export default () => {
…
como se exporta defult la pagina de Home?
Wuuaooo, muy interesante, Gracias!!
¿Quieres ver más aportes, preguntas y respuestas de la comunidad?
o inicia sesión.