¡Bienvenida! Este es un curso especial de React Hooks

1

¿Qué aprenderás en el Curso Profesional de React Hooks?

2

¿Qué son los React Hooks y cómo cambian el desarrollo con React?

Introducción a React Hooks

3

useState: estado en componentes creados como funciones

4

useEffect: olvida el ciclo de vida, ahora piensa en efectos

5

useContext: la fusión de React Hooks y React Context

6

useReducer: como useState, pero más escalable

7

¿Qué es memoization? Programación funcional en JavaScript

8

useMemo: evita cálculos innecesarios en componentes

9

useRef: manejo profesional de inputs y formularios

10

useCallback: evita cálculos innecesarios en funciones

11

Optimización de componentes en React con React.memo

12

Custom hooks: abstracción en la lógica de tus componentes

13

Third Party Custom Hooks de Redux y React Router

Configura un entorno de desarrollo profesional

14

Proyecto: análisis y retos de Platzi Conf Store

15

Git Hooks con Husky

16

Instalación de Webpack y Babel: presets, plugins y loaders

17

Configuración de Webpack 5 y webpack-dev-server

18

Configuración de Webpack 5 con loaders y estilos

19

Loaders de Webpack para Preprocesadores CSS

20

Flujo de desarrollo seguro y consistente con ESLint y Prettier

Estructura y creación de componentes para Platzi Conf Store

21

Arquitectura de vistas y componentes con React Router DOM

22

Maquetación y estilos del home

23

Maquetación y estilos de la lista de productos

24

Maquetación y estilos del formulario de checkout

25

Maquetación y estilos de la información del usuario

26

Maquetación y estilos del flujo de pago

27

Integración de íconos y conexión con React Router

Integración de React Hooks en Platzi Conf Merch

28

Creando nuestro primer custom hook

29

Implementando useContext en Platzi Conf Merch

30

useContext en la página de checkout

31

useRef en la página de checkout

32

Integrando third party custom hooks en Platzi Conf Merch

Configura mapas y pagos con PayPal y Google Maps

33

Paso a paso para conectar tu aplicación con la API de PayPal

34

Integración de pagos con la API de PayPal

35

Completando la integración de pagos con la API de PayPal

36

Paso a paso para conectar tu aplicación con la API de Google Maps

37

Integración de Google Maps en el mapa de checkout

38

Creando un Custom Hook para Google Maps

Estrategias de deployment profesional

39

Continuous integration y continuous delivery con GitHub Actions

40

Compra del dominio y despliega con Cloudflare

Optimización de aplicaciones web con React

41

Integración de React Helmet para mejorar el SEO con meta etiquetas

42

Análisis de performance con Google Lighthouse

43

Convierte tu aplicación de React en PWA

Bonus: trabaja con Strapi CMS para crear tu propia API

44

Crea una API con Strapi CMS y consúmela con React.js

¿Qué sigue en tu carrera profesional?

45

Próximos pasos para especializarte en frontend

No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Arquitectura de vistas y componentes con React Router DOM

21/45
Recursos

Aportes 46

Preguntas 11

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

Hola!
si no quieres tener cada importación en una linea de nuestro Archivo App.js
pueden hacer un archivo index.js en la carpeta containers.
adentro de este archivo van a importar todos los componentes, de la siguiente manera.

export { default as Home } from './Home'
export { default as CheckOut } from './CheckOut'
export { default as Information } from './Information'
export { default as Payment } from './Payment'
export { default as Success } from './Success'
export { default as NotFound } from './NotFound'

luego en nuestro archivo App.js hacemos la importancion de la siguiente manera

import { Home, CheckOut, Information, Payment, Success, NotFound } from "../containers"

o si quieren reducir aun mas el codigo

import * as Page from '../pages'

con esta segunda manera el sistema de rutas deben hacerlo asi.

import React from 'react'
import { BrowserRouter, Switch, Route } from 'react-router-dom'
import * as Page from '../pages'

const App = () => {
  return (
    <BrowserRouter>
      <Switch>
        <Route exact path="/">
          <Page.Home />
        </Route>
        <Route exact path="/checkout">
          <Page.CheckOut />
        </Route>
        <Route exact path="/checkout/information">
          <Page.Information />
        </Route>
        <Route exact path="/checkout/payment">
          <Page.Payment />
        </Route>
        <Route exact path="/checkout/success">
          <Page.Success />
        </Route>
        <Route>
          <Page.NotFound />
        </Route>
      </Switch>
    </BrowserRouter>
  )
}

export default App

cualquiera esta bien 😃 espero les sirva el aporte

Ojo: En la versión 6 en adelante de react-router-dom, Switch fue remplazado por Routes:

import { BrowserRouter, Routes, Route } from 'react-router-dom'

El uso es el mismo, pero cambian algunas cosas en la Route:

<BrowserRouter>
<Routes>
<Route path='/' element={<Home />} />
<Route path='/checkout' element={<Checkout />} />
<Route path='/checkout/information' element={<Information />} />
<Route path='/checkout/payment' element={<Payment />} />
<Route path='/checkout/success' element={<Success />} />
<Route path='*' element={<NotFound />} />
</Routes>
</BrowserRouter>

Documentación
Como ven en lugar de component se usa element y nos permite pasar un componente JSX. No se necesita el exact y para que reconozca cualquier otra página como NotFound se usa '*'
Me parece más semántico y fácil de entender el uso de Routes en lugar de Switch 😉

Bueno primero una critica al curso. Este es uno de los cursos donde no he tenido conflicto en entederle a Oscar. Pero esta desactualizado y si tienes React 18 es un dolor de cabeza hacer la migración y mas con webpack que es tan minucioso para configurar.

Sin no pueden actualizar el curso al menos entreguen una guia similar a la que adjunto

De otro lado les dejo los cambios para que puedan avanzar y no pierdan tanto tiempo como en mi caso:
**
idenx.js**

import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './routes/App';
import '../src/style/app.css';

ReactDOM.createRoot(document.getElementById('app')).render(
  <App />
)

**App.jsx
**

import React from "react";
import { BrowserRouter, Routes, Route } from "react-router-dom";

import {Home} from "../containers/Home";
import {Checkout} from "../containers/Checkout";
import {Success} from "../containers/Success";
import {Payment} from "../containers/Payment";
import {Information} from "../containers/Information";
import {NotFound} from "../containers/NotFound";

import '../style/app.css';

const App = () => {
  return (
    <BrowserRouter>
      <Routes>
        <Route exact path="/" element={<Home />}/>      
        <Route exact path='/checkout' element={<Checkout />} />
        <Route exact path='/checkout/information' element={<Information />} />
        <Route exact path='/checkout/payment' element={<Payment />} />
        <Route exact path='/checkout/success' element={<Success />} />
        <Route path='*' element={<NotFound />} />
      </Routes>
    </BrowserRouter>    
  );
};

export default App;

package.json

{
  "name": "conf-merch",
  "version": "1.0.0",
  "description": "App de venta en linea de productos promocionales de una conferencia",
  "main": "src/index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "webpack serve --mode development",
    "build": "webpack --mode production",
    "format": "prettier --write '{*.js,*/**/*.{js,jsx}}'",
    "lint": "eslint src/ --fix"
  },
  "repository": {
    "type": "git",
    "url": "git+ssh://[email protected]/joseluis1061/conf-merch.git"
  },
  "keywords": [
    "App",
    "ventas",
    "Java",
    "script",
    "Reack",
    "Hooks"
  ],
  "author": "JOSE LUIS ZUÑIGA <[email protected]>",
  "license": "MIT",
  "bugs": {
    "url": "https://github.com/joseluis1061/conf-merch/issues"
  },
  "homepage": "https://github.com/joseluis1061/conf-merch#readme",
  "husky": {
    "hooks": {
      "pre-commit": "npm test",
      "pre-push": "npm test",
      "...": "..."
    }
  },
  "dependencies": {
    "react": "^18.2.0",
    "react-autocomplete": "^1.8.1",
    "react-dom": "^18.2.0",
    "react-router-dom": "^6.3.0"
  },
  "devDependencies": {
    "@babel/core": "^7.18.5",
    "@babel/eslint-parser": "^7.18.2",
    "@babel/preset-env": "^7.18.2",
    "@babel/preset-react": "^7.17.12",
    "babel-loader": "^8.2.5",
    "css-loader": "^6.7.1",
    "eslint": "^8.17.0",
    "eslint-config-airbnb": "^19.0.4",
    "eslint-config-prettier": "^8.5.0",
    "eslint-plugin-import": "^2.26.0",
    "eslint-plugin-jsx-a11y": "^6.5.1",
    "eslint-plugin-prettier": "^4.0.0",
    "eslint-plugin-react": "^7.30.0",
    "html-loader": "^3.1.0",
    "html-webpack-plugin": "^5.5.0",
    "husky": "^8.0.1",
    "mini-css-extract-plugin": "^2.6.1",
    
    "webpack": "^5.73.0",
    "webpack-cli": "^4.10.0",
    "webpack-dev-server": "^4.9.2"
  }
}

webpack.config.js

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
  //Punto de entrada
  entry: './src/index.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js',
    publicPath: '/'
  },
  resolve: {
    extensions: ['.js', '.jsx'],
  },

  //Modulos que definen las reglas de optimización mediante loaders
  module: {
    rules: [
      //Optimización de JavaScript
      {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
        },
      },
      //Optimización de Html
      {
        test: /\.html$/,
        use: [
          {
            loader: 'html-loader',
          },
        ],
      },
      //Optimización CSS
      {
        test: /\.css$/,
        use: [
          {
            loader: MiniCssExtractPlugin.loader,
          },
          'css-loader',
        ],
      },
    ],
  },

  //Plugins para indicar las salidas
  plugins: [
    //Html
    new HtmlWebpackPlugin({
      template: './public/index.html',
      filename: './index.html',
    }),

    //Css
    new MiniCssExtractPlugin({
      filename: 'assets/[name].css',
    }),
  ],
  //Servidor de salida de la App
  devServer: {
    static: {
      directory: path.resolve(__dirname, "dist"),
    },
    devMiddleware: {
      index: 'index.html',
    },
    historyApiFallback: true,
    compress: true,
    port: 3000,
  },
};

Cada vez que editamos los archivos de configuración como webpack debemos volver a correr el comando npm start

Que onda!
He creado este boilerplate para hacer el proyecto en full Typescript. Me gustaria saber la opinion respecto a paquetes que se puedan aniadir o estructura en los archivos config:
Repositorio

Cosas a tener en cuenta, react-router-dom cambio los siguiente:

  • Ya no se usa Switch --> ahora es Routes
  • Ya no se usa component --> ahora es element
import {
  BrowserRouter,
  Routes,
  Route,
} from "react-router-dom";

function App() {
  return (
    <BrowserRouter>
        <Routes>
          <Route path="/" element={<Home />} />
        </Routes>
    </BrowserRouter>
  );
}

En React Router 6 se usa Routes en lugar de Switch y cambió un poco la forma de crear las rutas, el código actualizado quedaría como el siguiente, cuidado con la ruta Notfound.

import React from 'react';
import { BrowserRouter, Routes, Route } from 'react-router-dom';

import Home from '../containers/Home';
import Checkout from '../containers/Checkout';
import Information from '../containers/Information';
import Payment from '../containers/Payment';
import Success from '../containers/Success';
import NotFound from '../containers/NotFound';

const App = () => {
  return (
    <BrowserRouter>
        <Routes>
            <Route path="/" element={<Home />} />
            <Route path="/checkout" element={<Checkout />} />
            <Route path="/checkout/information" element={<Information />} />
            <Route path="/checkout/payment" element={<Payment />} />
            <Route path="/checkout/success" element={<Success />} />
            <Route path="*" element={<NotFound />} />
        </Routes>
      
    </BrowserRouter>
  )
}

export default App

npm install react-router-dom --save```

Hola, les dejo mi implementación en Nextjs:

https://github.com/danyel117/platzi-conf-store

Pueden buscar en los commits, el de la clase 21.

Para los que tengan algún problema como que no se muestre el contenido renderizado y tengan con resultado una pagina en blanco cuando esten usando el webpack-dev-server con el comando serve les recomiendo echar un ojo al objeto de configuracion devServer, asi me funciono a mi:

devServer: {
    static: {
      directory: path.resolve(__dirname, "dist"),
    },
    devMiddleware: {
      index: 'index.html',
    },
    historyApiFallback: true,
    compress: true,
    port: 3000,
  },

Observen que hay un objeto llamado devMiddleware que dentro tiene un index, este index hace refencia al archivo html que se genere dentro de la carpeta dist, es decir al filename que tengan configurado en su plugin HtmlWebpackPlugin

new HtmlWebpackPlugin({
      template: "./public/index.html",
      filename: "./index.html",
    }),

Como se realizaria en julio de 2022

import React from "react";
import {
    BrowserRouter,
    Routes,
    Route,
  } from "react-router-dom";
import { Checkout } from "../containers/Checkout";
import { Home } from "../containers/Home";
import { Information } from "../containers/Information";
import { Notfound } from "../containers/Notfound";
import { Success } from "../containers/Success";
import { Payment } from "../containers/Payment";

 const App = () => {
  return (
    <div>
        <BrowserRouter>
        <Routes>
            <Route  path="/" element={<Home/>}></Route>
            <Route  path="/checkout" element={<Route/>}></Route>
            <Route  path="/checkout/information" element={<Information/>}></Route>
            <Route  path="/checkout/payment" element={<Payment/>}></Route>
            <Route  path="/checkout/succes" element={<Success/>}></Route>
            <Route path="*" element={<Notfound/>}></Route>
        </Routes>
        </BrowserRouter>

    </div>
  )
}

export default App

El curso necesita actualización. El Switch cambio por Routes y la estructura también cambio, por lo que si lo hacen tan cual la clase, con la nueva versión de ‘react-router-dom’ no les va a correr.

import React from 'react';
import { BrowserRouter, Route, Switch } from 'react-router-dom';

import Home from '../container/Home'
import Checkout from '../container/Checkout'
import Information from '../container/Information'
import Payment from '../container/Payment'
import Success from '../container/Success'
import NotFound from '../container/NotFound'

const App = () => {
    return ( 
        <BrowserRouter>
            <Switch>
                <Route exact path='/' component={Home}/>
                <Route exact path='/checkout' component={Checkout}/>
                <Route exact path='/checkout/information' component={Information}/>
                <Route exact path='/checkout/payment' component={Payment}/>
                <Route exact path='/checkout/success' component={Success}/>
                <Route component={NotFound}/>
            </Switch>
        </BrowserRouter>
     );
}
 
export default App;

Puende usar

touch  Home.jsx Checkout.jsx Information.jsx Payment.jsx Success.jsx NotFound.jsx 

Para los que estan utilizando react 18 han cambiado muchas cosas, react router dom, se trabaja diferente.

import {createBrowserRouter,RouterProvider,} from "react-router-dom";
    const router = createBrowserRouter([
        {
          path: "/",
          element: <Home />,
        },
        {
          path: "checkout",
          element: <CheckOut />,
        },
        {
            path: "checkout/information",
            element: <Information />,
        },
        {
            path: "checkout/payment",
            element: <Payment />,
        },
        {
            path: "checkout/success",
            element: <Success />,
        },
        {
            path: "",
            element: <NotFound />,
        }
      ]); 
      <React.StrictMode>
          <RouterProvider router={router} />
      </React.StrictMode>

Hola, para los que tuvieron problemas para las rutas porque se les descargo “react-router-dom” a la versión 6, se tienen que hacer unos cambios ya que el Switch ya no se usa, les dejo mi codigo, en resumen, se cambio el Switch, se quito el component y se agrego el element y ahora los componentes se agregan como etiqueta

<code> 
import React from 'react'
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import Home from '../containers/Home';
import Checkout from '../containers/Checkout';
import Information from '../containers/Information';
import Payment from '../containers/Payment';
import Sucess from '../containers/Sucess';
import NotFound from '../containers/NotFound';

function App() {
    return (
        <BrowserRouter>
            <Routes>
                <Route exact path="/" element={<Home />} />
                <Route exact path="/checkout" element={<Checkout />} />
                <Route exact path="/checkout/information" element={<Information />} />
                <Route exact path="/checkout/payment" element={<Payment />} />
                <Route exact path="/checkout/success" element={<Sucess />} />
                <Route element={<NotFound />} />
            </Routes>
        </BrowserRouter>
    )
}


export default App

En la ultima version de react si estas teniendo problemas para hacer funcionar las rutas prueba agregando la extencion .jsx

<code> /* eslint-disable import/extensions */
import React from 'react';
import { BrowserRouter, Switch, Route } from 'react-router-dom';

import Home from '../containers/Home.jsx';
import Checkout from '../containers/Checkout.jsx';
import Information from '../containers/Information.jsx';
import Payment from '../containers/Payment.jsx';
import Success from '../containers/Success.jsx';
import NotFound from '../containers/NotFound.jsx';

const App = () => (
  <BrowserRouter>
    <Switch>
      <Route exact path="/" component={Home} />
      <Route exact path="/checkout" component={Checkout} />
      <Route exact path="/checkout/information" component={Information} />
      <Route exact path="/checkout/payment" component={Payment} />
      <Route exact path="/checkout/success" component={Success} />
      <Route component={NotFound} />
    </Switch>
  </BrowserRouter>
);

export default App;

Hola! en el rectángulo de comentarios cuando hay un error en VSC , me aparece el siguiente error:

Unexpected block statement surrounding arrow body; move the returned value immediately after the `=>`.eslintarrow-body-style

Es con base en arrow-body-style, alguien sabe como puedo corregirlo?
Este es mi archivo .eslinrc

Hoy 24/10 con react 18, hay algunas cosas que cambiaron: Aquí dejo como debería ir el código, para que pueda ejecutar sin errores
1.- En mi caso, le quite el exact.
2.- component, lo cambie por element y llame a los containers dentro de {< />}
3.- Tener en cuenta también en webpack.config.js, el: mode: ‘development’,
.

para los que usen react router dom 6

import React from "react";
import { Route, Routes } from "react-router-dom";
import Home from "../containers/Home";
import CheckOut from "../containers/CheckOut";
import Information from "../containers/Information";
import Payment from "../containers/Payment";
import Success from "../containers/Success";
import NotFound from "../containers/NotFound";
const App =()=>{
    return(
        <Routes>
            <Route exact path="/" element={<Home />} />
            <Route exact path="/checkout" element={<CheckOut />} />
            <Route exact path="/checkout/information" element={<Information />} />
            <Route exact path="/checkout/payment" element={<Payment />} />
            <Route exact path="/checkout/success" element={<Success />} />

            <Route path="*" element={<NotFound />} />
        </Routes>
    )
}
export default App;

nueva forma de routear

import { BrowserRouter, Route, Routes } from “react-router-dom”;
import Home from “…/containers/Home”;
import Checkout from “…/containers/Checkout”;
import Information from “…/containers/Information”;
import NotFound from “…/containers/NotFound”;
import Payment from “…/containers/Payment”;
import Sucess from “…/containers/Sucess”;

export default () => {
return (
// <h1>alas</h1>
<BrowserRouter>
<Routes>
<Route exact path="/" element={<Home />} />
<Route exact path="/checkout" element={<Checkout />} />
<Route exact path="/checkout/information" element={<Information />} />
<Route exact path="/checkout/payment" element={<Payment />} />
<Route exact path="/checkout/success" element={<Sucess />} />
<Route path="*" element={<NotFound />} />
</Routes>
</BrowserRouter>
);
};

un curso muy desactualizado, oscar explica bien pero hoy 28 de sep de 2022 al hacer el curso segun como lo explica le van a dar un mundo de errores

Si no te cargan las rutas puedes cambiar Switch por Routes en la importacion de react-router-dom tambien cambiamos component y por element y los componentes los traemos en forma de tag tipo HTML como se muestra a continuacion

import React from 'react';
import { BrowserRouter,Routes, Route} from 'react-router-dom';
import { Home } from '../containers/Home';
import { Checkout } from '../containers/Checkout';
import { Information } from '../containers/Information';
import { Payment } from '../containers/Payment';
import Success from '../containers/Success';
import NotFound from '../containers/NotFound';
import '../styles/components/App.css';

function App() {
  return (
    <BrowserRouter>
      <Routes>
        <Route exact path='/' element={<Home/>} />
        <Route exact path='/checkout' element={<Checkout/>} />
        <Route exact path='/checkout/information' element={<Information/>} />
        <Route exact path='/checkout/payment' element={<Payment/>} />
        <Route exact path='/checkout/success' element={<Success/>} />
        <Route element={<NotFound/>} />
      </Routes>
    </BrowserRouter>
  );
}

export default App;

Si empiezas a realizar un proyecto desde cero hoy en dia, la manera de utilizar react-router-dom es la siguiente

import { BrowserRouter, Routes, Route }  from "react-router-dom"

return(
  <BrowserRouter>
      <Routes>
          <Route path="/" element={<Home />} />
      </Routes>
  </BrowserRouter>
)

Para los que tienen problema con la biblioteca react-router-dom apartir de la versión 6 “Switch” se reemplaza por “Routes” y necesitas actulizar la importación desde:

import { Switch, Route } from "react-router-dom"; 

a

import { Routes ,Route } from 'react-router-dom';

También deben de actualizar las declaraciones de ruta de

<Route path="/" component={Home} />

a

<Route path='/welcome' element={<Home/>} />

En react-router-dom, tampoco necesita usar la declaración de ruta exacta.
Para obtener más información, pueden visitar los documentos oficiales: https://reactrouter.com/docs/en/v6/upgrading/v5

Bastante detallado y rápido

Si estuviste teniendo problemas con las rutas vengo a comentarles una solución para la version 6.8.0 de react-router.
Oscar usa layout como home, por lo que la unica manera de que la ruta ’ / ’ incluya el componente Home y que desaparezca cuando vamos al resto de paginas es asignar a Layout como pagina principal y como hijo a a Home, tambien con la misma ruta. Dejo el codigo

import React from 'react';
import ReactDOM from 'react-dom/client';
import {
  createBrowserRouter as Router,
  RouterProvider,
} from 'react-router-dom';

import Home from './containers/Home';
import Checkout from './containers/CheckOut';
import Information from './containers/Information';
import Payment from './containers/Payment';
import Success from './containers/Sucess';
import NotFound from './containers/NotFound';
import Layout from './components/Layout';

const router = Router([
  {
    path: '/',
    element: <Layout />,
    errorElement: <NotFound />,
    children: [
      {
        path: '/',
        element: <Home />,
      },
      {
        path: 'checkout',
        element: <Checkout />,
      },
      {
        path: 'checkout/information',
        element: <Information />,
      },
      {
        path: 'checkout/payment',
        element: <Payment />,
      },
      {
        path: 'checkout/success',
        element: <Success />,
      },
      {
        path: '',
        element: <NotFound />,
      },
    ],
  },
]);

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <RouterProvider router={router} />
  </React.StrictMode>
);

Esto va en main.jsx (yo use vite, porque tuve un par de problemas con webpack y quise avanzar con el curso). Asi que la carpeta routes con el componenete App pueden borrarlo. El resto, tanto layout como home quedan igual que coo lo viene haciendo oscar. Solo que no hace falta importar react en cada archivo, basta con hacerlo en main.jsx.

Aparte de actualilzar a 2020 en App.jsx cambiando Switch por Routes y modificar el path a exact path, si les sale el error o warning: Parsing error: require() of ES Module

Deben agregar en el archivo webpack.config.js la linea: mode: ‘development’ y ahí funciona todo

Actualización 7 septiembre 2022

Estructura de las rutas:

import React from 'react';
import { BrowserRouter, Routes, Route } from 'react-router-dom';

import Home from '../containers/Home'
import Checkout from '../containers/Checkout'
import Information from '../containers/Information'
import Payment from '../containers/Payment'
import Success from '../containers/Success'
import NotFound from '../containers/NotFound'


const App = () => {
  return (
    <BrowserRouter>
      <Routes>
        <Route index path='/' element={<Home />} />
        <Route path='/checkout' element={<Checkout />} />
        <Route path='/information' element={<Information />} />
        <Route path='/payment' element={<Payment />} />
        <Route path='/success' element={<Success />} />
        <Route path='*' element={<NotFound />} />
      </Routes>
    </BrowserRouter>
  )
}

export default App

Webpack config:

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
  entry: './src/index.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'main.js',
    publicPath: '/',
  },

  resolve: {
    extensions: ['.js', '.jsx'],
  },

  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        exclude: /node-modules/,
        use: {
          loader: 'babel-loader',
        },
      },
      {
        test: /\.html$/,
        use: [
          {
            loader: 'html-loader',
          },
        ],
      },
      {
        test: /\.css$/i,
        use: [MiniCssExtractPlugin.loader, "css-loader"],
      },
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './public/index.html',
      filename: './index.html',
    }),
    new MiniCssExtractPlugin({
      filename: 'assets/[name].css',
    }),
  ],
  devServer: {
    static: path.join(__dirname, 'dist'),
    compress: true,
    port: 3000,
    historyApiFallback: true,
    open:true,
  },
};

Packaga json:

{
  "name": "platzi-conf-merch",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "webpack serve --mode=development",
    "build": "webpack --mode=production",
    "format": "prettier --write '{*.js,src/**/*.{js,jsx}}'",
    "lint": "eslint src/ --fix"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@babel/eslint-parser": "^7.18.9",
    "eslint": "^8.23.0",
    "eslint-config-airbnb": "^19.0.4",
    "eslint-config-prettier": "^8.5.0",
    "eslint-plugin-import": "^2.26.0",
    "eslint-plugin-jsx-a11y": "^6.6.1",
    "eslint-plugin-prettier": "^4.2.1",
    "eslint-plugin-react": "^7.31.7",
    "prettier": "^2.7.1",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-router-dom": "^6.3.0"
  },
  "devDependencies": {
    "@babel/core": "^7.19.0",
    "@babel/preset-env": "^7.19.0",
    "@babel/preset-react": "^7.18.6",
    "babel-loader": "^8.2.5",
    "css-loader": "^6.7.1",
    "html-loader": "^4.1.0",
    "html-webpack-plugin": "^5.5.0",
    "mini-css-extract-plugin": "^2.6.1",
    "webpack": "^5.74.0",
    "webpack-cli": "^4.10.0",
    "webpack-dev-server": "^4.10.1"
  }
}

Otra opción para creer el componente por defecto de React es rafc
Sale con un export nombrado, por lo que no te olvides de usar llaves { } al importar el componente.

Mi script

"start": "webpack serve --mode development"

Los aportes de la clase me salvaron. ¡Gracias a todos!

Hola, para la versión de react-router-dom@6 cambia un poco, aquí les dejo el código:

import React from "react";
import { BrowserRouter, Routes, Route } from "react-router-dom";

import Home from "../containers/Home";
import Checkout from "../containers/Checkout";
import Success from "../containers/Success";
import Payment from "../containers/Payment";
import NotFound from "../containers/NotFound";
import Information from "../containers/Information";

const App = () => {
    return(
        <BrowserRouter>
            <Routes>
                <Route exact  path="/" element={<Home />}/>
                <Route exact path="checkout" element={<Checkout />} />
                <Route exact path="checkout/information" element={<Information />}/>
                <Route exact path="checkout/payment" element={<Payment />}/>
                <Route  exact path="checkout/success" element={<Success />}/>
            
                <Route path="*" element={<NotFound />}/>
            </Routes>
        </BrowserRouter>
    )
}

export default App;

El curso es genial no paren de aprender ! , me ahorre ya 2 horas de configuración con Next Js 😃 !

Para aquellos que tengan error con el router pueden usar:
element en vez de component.

<Route path="/" element={<Home />}></Route>

¡Hola! Estoy siguiendo este curso, pero usando NextJS + TypeScript. Aún no lo termino, pero voy agregando poco a poco las cosas que vamos viendo.

Si les interesa ver el proyecto hasta esta clase, les dejo el link del proyecto: https://github.com/d4vsanchez/platzi-conf-merch/tree/configure-routes

21.-Arquitectura de vistas y componentes con React Router DOM

Instalamos:

npm install react-router-dom --save
//Para poder manejar las rutas de nuestra aplicación

Lo configuramos dentro de routes/App.jsx

import React from "react";
import { BrowserRouter, Switch, Route } from "react-router-dom";
import { Home } from "../containers/Home";
import { Checkout } from "../containers/Checkout";
import { Information } from "../containers/Information";
import { Payment } from "../containers/Payment";
import { Success } from "../containers/Success";
import { NotFound } from "../containers/NotFound";

function App() {
  return (
    <BrowserRouter>
      <Switch>
        <Route exact path="/" component={Home}></Route>{" "}
        {/*Exacta, con path especifico aquí  es el index y un componente*/}
        <Route exact path="/checkout" component={Checkout}></Route>
        <Route
          exact
          path="/checkout/information"
          component={Information}
        ></Route>
        <Route exact path="/checkout/payment" component={Payment}></Route>
        <Route exact path="/checkout/success" component={Success}></Route>
        <Route component={NotFound}></Route>{" "}
        {/*Ruta 404 cuando sucede un error*/}
      </Switch>
    </BrowserRouter>
  ); //Para encapsular la navegación, switch para mostrar el que coincida con la ruta que elijo.
} //Rutas que voy a manejar con route

export { App };

En webpack:

module.exports = {
  entry: "./src/index.js",
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "bundle.js",
    publicPath: "/",
  },
}
devServer: {
    static: path.join(__dirname, "dist"),
    compress: true,
    historyApiFallback: true,
    port: 3000,
    open: true,
  },

mucha compresion la voz de oscar

Para cambiar el nombre de un componente (o variable en general) en VSCode sólo tenemos que hacer clic derecho sobre el nombre del componente/variable/función y seleccionar rename symbol/renombrar símbolo y colocar el nuevo nombre que queremos darle, y listo, evitamos tener que renombrar archivo por archivo.

de 10 este curso! si bien tipear todo a veces da error pero después de eso, muy genial la explicación y se ha avanzado rápido. más cursos así!

Un par de shortcuts de VSCode para react:
Para crear una función:

rfce
Crea la función, incluyendo el import React…

rafce
Crea una arrow function, incluyendo el import React…

¿Alguien conoce cuál es la extensión que utiliza Oscar para crear rápidamente las clases en los archivos?

Usando un snipet en vscode crea los componentes con el nombre de archivo.
https://marketplace.visualstudio.com/items?itemName=dsznajder.es7-react-js-snippets

Crean el nuevo archivo .jsx con el nombre y luego usan el snippet

rafce

y eso les crea la base de cada componente con el nombre correspondiente, para no tener que copiar, pegar y renombrar

Genial. Hasta éste punto, funciona como para un proyecto base (config manual) con React, React-Router, Webpack, Eslint, Prettier

m