Gaston Blanco
Un comando interesante para cuando estamos creando nuestros componentes es **rfcp ** o **rafc **(abreviatura de React Functional Component)
Seba Cardoso
Necesitas una extension?? Porque a mi no me funciono
Gaston Blanco
Configurar la navegación en una aplicación React deja de ser un misterio cuando entiendes cómo funcionan los componentes base de React Router Dom 6. Aquí aprenderás a definir rutas, manejar páginas no encontradas y estructurar tu app para que el menú y el footer convivan con el contenido dinámico, todo usando un proyecto creado con Create React App.
¿Qué componentes necesitas para empezar con React Router Dom 6?
Antes de escribir la primera ruta, importa los tres pilares que sostienen toda la navegación.
En versiones anteriores, Routes se llamaba Switch y las propiedades como element se llamaban component o render. Si estás migrando desde una versión vieja, este es el cambio más visible.
¿Cuándo debo usar HashRouter en lugar de BrowserRouter? Úsalo cuando vayas a desplegar en servicios como GitHub Pages que no manejan bien el routing del lado del servidor. El HashRouter agrega un
#antes de la ruta para que el navegador no haga peticiones reales al servidor.
¿Cómo se estructura el componente App con rutas dinámicas?
La idea es envolver toda tu aplicación en el HashRouter, que funciona como un provider (igual que React Context, solo que más bonito). Dentro de ese provider colocas lo que quieres que aparezca en todas las páginas, como el menú, y luego defines la zona dinámica con Routes.
jsx <HashRouter>
<Menu /> <Routes> <Route path="/" element={<HomePage />} /> <Route path="/blog" element={<BlogPage />} /> <Route path="/profile" element={<ProfilePage />} /> <Route path="*" element={<NotFound />} /> </Routes> </HashRouter>Fíjate en algo importante: el componente Route no se abre y se cierra como un contenedor tradicional. Funciona como un self-closing tag que recibe dos propiedades clave: path y element. En element pasas directamente el componente JSX que quieres renderizar.
¿Por qué el menú debe ir dentro del HashRouter?
Esta es una decisión de diseño que evita dolores de cabeza después. Si dejas el menú fuera del HashRouter, ese menú no podrá acceder a la información del provider. Eso significa que no podrás navegar programáticamente desde el menú, ni leer la ruta actual, ni hacer redirecciones cuando implementes autenticación.
Mantén el menú adentro del router pero afuera de Routes, así se renderiza en todas las páginas y a la vez tiene acceso al contexto de navegación.
¿Cómo manejar rutas no encontradas con el asterisco?
El truco del asterisco es una de las gemas más útiles de React Router. Cuando defines un Route con path="*", le estás diciendo: "si ninguna ruta anterior coincidió, renderiza esto".
¿Qué hace el asterisco en React Router? Captura cualquier URL que no haya hecho match con las rutas definidas arriba. Sirve para mostrar una página not found cuando el usuario escribe una ruta que no existe.
El orden importa. Si pones el asterisco al inicio, todas las rutas mostrarán not found porque el match se hace de arriba hacia abajo. Déjalo siempre al final.
¿Cómo crear los componentes de página paso a paso?
Cada página es un componente React común y corriente. Por convención, conviene exportarlos con named exports en lugar de default exports para evitar typos al importarlos en otros archivos.
jsx import React from 'react';
export function HomePage() { return <h1>HomePage</h1>; }
Replica esa estructura para BlogPage.js, ProfilePage.js y un Menu.js que contenga una <navbar> simple. Visual Studio Code te ayuda a importar automáticamente, pero el concepto es el mismo: cada archivo exporta su componente y App.js los consume.
¿Qué pasa con las URLs cuando usas HashRouter?
Aquí viene un detalle que confunde a muchos. Como estás usando hash navigation, las rutas no funcionan escribiendo /blog directamente en el navegador. Tienes que escribir /#/blog para que el router las interprete correctamente.
/#/./#/blog, /#/profile, etc./#/cualquiercosa, se renderiza el componente not found./blog/lalala, el router las interpreta como ruta principal y muestra el home.Si cambiaras el HashRouter por un BrowserRouter, no tendrías que preocuparte por los hashes. Las rutas dentro de tu código siguen siendo /, /blog, /profile, sin importar el tipo de router. El provider se encarga de agregar los hashes cuando es necesario.
En la siguiente etapa toca aprender a navegar entre páginas sin cambiar la URL manualmente, usando los componentes Link y NavLink. Cuéntame en los comentarios qué tipo de router elegiste para tu proyecto y por qué.
Gaston Blanco
Un comando interesante para cuando estamos creando nuestros componentes es **rfcp ** o **rafc **(abreviatura de React Functional Component)
Seba Cardoso
Necesitas una extension?? Porque a mi no me funciono
Gaston Blanco
Andrés Esteban Rodríguez Jiménez
Julian Franco
El atajo de VS Code por default es alt + space recuerden que deben tener abiertos los componentes para que les de el path.
Arturo Mauricio Terceros Beltrán
Ctrl + space. Deben estar abiertos los componentes.
Nicolas Forero Quevedo
Nicolas Forero Quevedo
doc react router ese es el link de la documentacion
Ignacio Basilio
Geovanny Sneyder Paez Pabon
Me coloque a experimentar que pasaba si cambiaba el hash con un onClick en el componente <Menu/> y a si fue el resultado.
import React from "react"; export function Menu (){ return ( <nav> <ul> <li onClick={()=>location.hash='#/'}>Home</li> <li onClick={()=> location.hash='#/profile'}>Profile</li> <li onClick={()=> location.hash= '#/blog'}>BLog Page</li> </ul> </nav> ) }
Asi dinamicamente cambiamos la direccion o el hash de la pagina y el react router atomaticamente nos renderiza los componentes que esten ligados a ese hash
Angel David Contreras Barrios
Excelente clase!!👏👏, por fin aclare las dudas del Curso Practico de React. . 😅😅Me atrevo a decir que tome primero el Practico de React. Por que este curso no estaba disponible.
Harold Zurita Simon
Enna Velasquez Botache
el comando rafce, con la extensión code snipets en vsc crea el componente automáticamente
Raycris Maldonado
Victor Hugo Cruz Carballo
Tomas de Miguel
Por que se pone, HomePage.js y no poner PageHome.jsx?
Juan Diego Mejia Maestre
Paola Marcela Arguelles Salazar
Tengo este error me podrian ayudar
Failed to compile.
[eslint] Plugin "react" was conflicted between "package.json » eslint-config-react-app » C:\Users\Usuario\Desktop\PLATZI\Curso React\my-react-app\node_modules\eslint-config-react-app\base.js" and "BaseConfig » C:\Users\Usuario\Desktop\PLATZI\curso react\my-react-app\node_modules\eslint-config-react-app\base.js". ERROR in [eslint] Plugin "react" was conflicted between "package.json » eslint-config-react-app » C:\Users\Usuario\Desktop\PLATZI\Curso React\my-react-app\node_modules\eslint-config-react-app\base.js" and "BaseConfig » C:\Users\Usuario\Desktop\PLATZI\curso react\my-react-app\node_modules\eslint-config-react-app\base.js".
webpack compiled with 1 error
Andres Prieto
Si meto un BrowserRouter para las 404 ¿Estoy profanando el router?
Juan Castro
ProfesorJajajaja depende, cómo lo piensas hacer?
Juan Mercado
Routes es un provider?
Juan Castro
ProfesorPuedes descubrirlo tú mismo en el repo de RR: https://github.com/remix-run/react-router/tree/main
Gualberto Montiel
buena clase, he visto que ahora y ano se ocupa importar react from react, es debido a la nueva versio de react o algo asi?
Juan Castro
ProfesorLa configuración de CRA lo hace por defecto. Por si las moscas sí deberíamos importarlo. :sweat_smile:
Juan Castro
ProfesorDaniel Velasco
tengo una duda, me gusta poner el BrowserRouter o este caso el HashRouter en el index del la app para que se vea mas clene, me puede dar un problema a futuro o algún tipo de conflicto o pasa nada
Juan Castro
ProfesorNah, no pasa nada. A mí me gusta más ponerlo en el componente App, pero nomás es cuestión de gustos.
Route: componentes de navegación
Vamos a crear nuestras primeras rutas con React 😀.
En nuestro archivo App vamos a importar un par de componentes que nos da React Router DOM:
import { HashRouter, Routes, Route } from 'react-router-dom';
Luego en nuestro componente App vamos a escribir un código de ejemplo para entender como funcionan estos componentes.
function App() { return ( <> {/* Este es un provider */} <HashRouter> <Menu /> {/* Esta es la parte de la aplicación que va cambiar de manera dinámica según las rutas */} <Routes> {/* Este componente recibe las propiedades de 'path', que es la ruta deseada y 'element', que es componente que deseamos renderizar */} <Route path='/' element={<HomePage />} /> <Route path='/blog' element={<BlogPage />} /> <Route path='/profile' element={<ProfilePage />} /> </Routes> </HashRouter> </> ) }
Podemos agregar una ruta al final que sea para todas las rutas que no hayamos definido, esto lo hacemos añadiendo un '*' en la propiedad path de nuestra ruta, si lo hacemos al final de todas las rutas en caso de que no estén definidas retornará algo que nosotros definamos, con esto por ejemplo podemos crear una página de no encontrado.
<Route path='*' element={<p>Not Found</p>} />
Ahora debemos crear estos componentes que añadimos en los path ya que estos no existen.
HomePage.js
import React from 'react'; function HomePage() { return ( <h2>Home Page</h2> ); } export { HomePage }
BlogPage.js
import React from 'react'; function BlogPage() { return ( <h2>Blog Page</h2> ); } export { BlogPage }
ProfilePage.js
import React from 'react'; function ProfilePage() { return ( <h2>Profile Page</h2> ); } export { ProfilePage }
Menu.js
import React from 'react'; function Menu() { return ( <nav>Menú</nav> ); } export { Menu }
Y los importamos a nuestro archivo App:
import { Menu } from './Components/Menu/Menu'; import { HomePage } from './Components/Routes/HomePage/HomePage'; import { BlogPage } from './Components/Routes/BlogPage/BlogPage'; import { ProfilePage } from './Components/Routes/ProfilePage/ProfilePage';
Si jugamos con la ruta usando los hast navigaror /#/ veremos que efectivamente si funcionan y cargan nuestros componentes.
estoy usando reacto router 6.8 y cambio muchisimo, para usarlo ahora es asi:
import Menu from './Menu'; import './index.css'; //* /#/ //* /#/blog //* /#/profile //* /#/lalala -> not found const router = createHashRouter([ { path: '/', element: <HomePage />, }, { path: '/blog', element: <BlogPage />, }, { path: '/profile', element: <ProfilePage />, }, { path: '*', element: <p>Not Found</p>, }, ]); ReactDOM.createRoot(document.getElementById('root')).render( <React.StrictMode> <Menu /> <RouterProvider router={router} /> </React.StrictMode> );
ahora se usa create hash router y un routerProvider, para mas info en la documentacion:
El código de App.js, por si lo necesitan:
import { HashRouter, Route, Routes } from 'react-router-dom' import { BlogPage } from './BlogPage'; import { HomePage } from './HomePage'; import { Menu } from './Menu'; import { ProfilePage } from './ProfilePage'; import React from 'react' function App() { return ( <> <HashRouter> <Menu/> <Routes>//Esta parte va a ser dinamica, osea que va a cambiar dependiendo de la ruta en la que estemos <Route path='/' element={<HomePage/>}/> <Route path='/blog' element={<BlogPage/>}/> <Route path='/profile' element={<ProfilePage/>}/> <Route path='/*' element={<p>Not found</p>}/>//Cuando ponemos un asterisco (*) nos referimos a que sea el valor por defecto si las rutas de arriba no se cumple. </Routes> </HashRouter> </> ); } export default App;
Route: componentes de navegación
.
Vamos a empezar a crear nuestras primeras rutas con React Router DOM 6 y vamos a utilizar HashRouter.
.
En nuestro archivo App.js vamos a importar algunos componentes desde react-router-dom:
.
BrowserRouter o un MemoryRouter, sin embargo utilizaremos un HashRouter debido a que planeamos desplegarlo en GitHub Pages. Este componente funge de provider.
..
import { HashRouter, Routes, Route } from 'react-router-dom'; import { Menu } from './Menu'; import { HomePage } from './HomePage'; import { BlogPage } from './BlogPage'; import { ProfilePage } from './ProfilePage'; function App() { return ( <> <HashRouter> <Menu /> <Routes> <Route path="/" element={<HomePage />} /> <Route path="/blog" element={<BlogPage />} /> <Route path="/profile" element={<ProfilePage />} /> <Route path="*" element={<p>Not found</p>} /> </Routes> </HashRouter> </> ); } export default App;
.
Lo primero que podemos observar es que nuestro componente HashRouter va a contener a los demás componentes, esto porque es un provider. Lo que pongamos adentro que esté por de fuera de Routes se va a renderizar en todas las páginas, como en este caso el componente Menu.
.
Como dijimos, vamos a también tener nuestras rutas dinámicas dentro de un componente Routes, que sin embargo dependiendo de la versión que estemos utilizando podría cambiar de nombre a Switch por ejemplo.
.
Dentro de Routes tendremos a las rutas Route en sí, cada una de ellas define una ruta que tiene como propiedades al path y al element. Normalmente este componente no se abre y se cierra, solo se cierra.
.
En nuestro componente Route la propiedad path define la ruta que va después de /#/. La propiedad element que dependiendo de la versión y el tipo de React Router que estemos utilizando, puede cambiar de nombre a render o component, sin embargo independientemente del nombre que tenga lo que hace es indicar qué componente se va a renderizar cuando accedamos a la ruta definida en la propiedad path.
.
Las rutas definidas en Routes son algo independientes del tipo de router; es decir, que no saben si estamos utilizando un hash router o un browser router. Por lo que si decidimos cambiar el tipo de router no tendremos que modificar las rutas porque por si solas se acoplaran después de un /#/ si estuviéramos utilizando un HashRouter o directamente después del / si estamos utilizando un BrowserRouter. Debido a ello en la propiedad path del componente Router ponemos las rutas de forma normal, luego nuestro provider se encargará de ponerle los hashes si este lo requiere.
.
Como podemos contemplar hemos creado varias rutas que renderizarán un componente en específico dependiendo de la ruta en la que estamos. Sin embargo, una de esas rutas es simplemente un * que significa cualquier ruta que no hayamos definido anteriormente, a lo cual vamos a responder renderizando un Not Found. Esta ruta genérica es recomendable posicionarla al final para evitar posibles conflictos; dependiendo de la versión que utilicemos, el colocarlo como primera ruta podría significar que las consecuentes no se lean, dando Not Found para todas las rutas.
.
En cuanto al componente Menu es importante que esté por dentro del componente HashRouter debido a que de esta forma va a poder consumir la información del provider.
.
Finalmente, se deben de realizar las importaciones correspondientes y la creación de los componentes que se renderizan en las distintas rutas.
.
Como estamos utilizando lo que es HashRouter si yo en la url no pongo la ruta después de /#/, entonces no va a funcionar; incluso si pongo cualquier cosa donde se supone que me responda con Not Found, me seguirá dando la página principal.
.
/#/ -> HomePage /#/blog -> BlogPage /#/profile -> ProfilePage /#/lalalala -> Not Found /blog, /lalala -> HomePage
Gracias a esta clase pude mejorar un poco un proyecto personal que había hecho anteriormente, que pasa el proyecto es una tienda de tenis(calzados) entonces quería que todo el nav bar y el footer se expadiera por toda la aplicación y poder buscar los articulos. Antes de este cambio tenia el footer y el header harcodeado en cada una de las pantallas y solo en la pantalla de home podia hacer las busqueda de los productos. Pero con el cambio todo mejoró aquí le dejo un antes y un después. Las partes subrayadas en rojo fueron agregadas con el nuevo cambio!
ANTES
import React from "react"; import { Route, Routes } from "react-router-dom"; import "./App.css"; import { useUserContext } from "./context/userContext"; import { auth } from "./firebase/credenciales"; import { onAuthStateChanged } from "firebase/auth"; import { Home, Product, Profile, Cart, Checkout, Login, NotFound, } from "./views"; function App() { const { user, setUser } = useUserContext(); onAuthStateChanged(auth, (firebaseUser) => { firebaseUser ? setUser(firebaseUser) : setUser(null); }); return ( <Routes> <Route path="/" element={<Home />} /> <Route path="product/:id" element={<Product />} /> <Route path="profile" element={<Profile />} /> <Route path="cart" element={<Cart />} /> <Route path="checkout" element={<Checkout />} /> <Route path="login" element={<Login />} /> <Route path="*" element={<NotFound />} /> </Routes> ); } export default App;
DESPUES
ARCHIVO HOME.JSX
++ANTES++
import React, { useState, useEffect } from "react"; import styled from "styled-components"; import Header from "../components/header"; import ItemCard from "../components/ItemCard"; import getActiveProducts from "../functions/getActiveProducts"; import Hero from "../assets/images/inicio.jpg"; const Home = () => { const [products, setProducts] = useState(null); const [searchValue, setSearchValue] = useState(""); let searchedItems = []; useEffect(() => { async function getProducts() { const products = await getActiveProducts(); setProducts(products); } getProducts(); }, []); if (!searchValue.length >= 1) { searchedItems = products; } else { searchedItems = products.filter((product) => { const productName = product.name.toLowerCase(); const searchText = searchValue.toLowerCase(); return productName.includes(searchText); }); } return ( <Container> <HeroContainer> <Header setSearchValue={setSearchValue} searchValue={searchValue} /> <HeroImage src={Hero} alt="hero" /> </HeroContainer> <ListContainer> {searchedItems ? searchedItems.map((itemProduct) => ( <li key={itemProduct.id}> <ItemCard product={itemProduct} /> </li> )) : null} </ListContainer> </Container> ); }; export default Home; const Container = styled.div` display: flex; flex-direction: column; @media (min-width: 768px) { gap: 10px; align-items: center; justify-content: space-around; } `; const ListContainer = styled.ul` padding: 0; list-style: none; justify-content: center; @media (min-width: 768px) { gap: 10px; display: grid; grid-template-columns: repeat(2, 1fr); } @media (min-width: 1024px) { grid-template-columns: repeat(3, 1fr); } @media (min-width: 1440px) { grid-template-columns: repeat(4, 1fr); } `; const HeroContainer = styled.picture` width: 100%; `; const HeroImage = styled.img` width: 100%; height: auto; min-width: 288px; background-size: cover; `;
import React from 'react'; import { HashRouter, Routes, Route } from 'react-router-dom' import { HomePage } from './pages/HomePage'; import { BlogPage } from './pages/BlogPage'; import { ProfilePage } from './pages/ProfilePage'; import { Menu } from './components/Menu'; function App() { return ( <> <HashRouter> <Menu /> <Routes> <Route path='/' element={<HomePage />} /> <Route path='/blog' element={<BlogPage />} /> <Route path='/profile' element={<ProfilePage />} /> <Route path='*' element={<p>Not found</p>} /> </Routes> </HashRouter> </> ); } export default App;
🗺️ Resumen: Creación de Rutas Dinámicas con React Router DOM
Aprender a gestionar rutas en React se vuelve sencillo con React Router DOM. El proceso implica importar componentes clave y estructurar la aplicación para definir qué contenido se muestra en cada URL.
⚛️ Componentes Fundamentales
Para iniciar el enrutamiento, necesitas tres componentes esenciales:
HashRouter, BrowserRouter, o MemoryRouter): Envuelve toda la aplicación. Se recomienda usar HashRouter para despliegues fáciles (ej. GitHub Pages).Routes (Contenedor de Rutas): Este componente define el área donde el contenido cambiará dinámicamente. Todas las rutas individuales deben estar anidadas dentro de él.Route (Definición de Ruta): Asocia una URL específica (definida por el prop path) con el componente de React que debe renderizarse (definido por el prop element).🛠️ Estructura de la Implementación
Las rutas se insertan en el componente principal (App.js) siguiendo esta jerarquía:
JavaScript
import { HashRouter, Routes, Route } from 'react-router-dom'; function App() { return ( <HashRouter> {/* Componentes estáticos visibles en todas las páginas, como el <Menu /> */} <Routes> <Route path="/" element={<HomePage />} /> <Route path="/blog" element={<BlogPage />} /> {/* ... otras rutas ... */} {/* Manejo de rutas no encontradas */} <Route path="*" element={<NotFoundPage />} /> </Routes> </HashRouter> ); }
📄 Componentes de Página
Para cada Route, debes crear un componente de React correspondiente. Por ejemplo:
JavaScript
export const HomePage = () => { return <h1>Home Page</h1>; };
🚨 Manejo de Rutas No Encontradas
Para una buena experiencia de usuario, se debe incluir un Route especial con path="*". Este actúa como un catch-all, asegurando que cualquier URL indefinida muestre un componente de error (<NotFoundPage />).
🍔 Componentes Comunes (Menú de Navegación)
Para que un componente, como un menú, sea visible en todas las rutas, debe estar ubicado dentro del HashRouter pero fuera del contenedor Routes. Esto garantiza que el menú tenga acceso a la información de navegación para poder utilizar componentes como Link y NavLink.