隆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 10

Ordenar por:

驴Quieres ver m谩s aportes, preguntas y respuestas de la comunidad?

o inicia sesi贸n.

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>
  );
}
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 鈥榬eact-router-dom鈥 no les va a correr.

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

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 鈥渞eact-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

nueva forma de routear

import { BrowserRouter, Route, Routes } from 鈥渞eact-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 鈥淪witch鈥 se reemplaza por 鈥淩outes鈥 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

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;

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.

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: 鈥榙evelopment鈥,
.

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: 鈥榙evelopment鈥 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 [email protected] 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