Principales cambios en React Router
React Router v6+ introduce varios cambios significativos respecto a versiones anteriores. Estos cambios están diseñados para mejorar la experiencia de desarrollo y la eficiencia en la navegación dentro de aplicaciones React.
Nuevos métodos create
: Uno de los cambios más importantes es la introducción de los métodos createBrowserRouter
, createHashRouter
y createMemoryRouter
. Estos métodos proporcionan una forma más directa y flexible de configurar el enrutamiento en lugar de usar los componentes BrowserRouter
, HashRouter
y MemoryRouter
tradicionales. Por ejemplo, createBrowserRouter
permite definir rutas y su configuración directamente en el archivo de enrutamiento, lo que facilita la gestión y lectura del código.
Método createBrowserRouter
El método createBrowserRouter
es una de las nuevas incorporaciones en React Router v6+ Este método proporciona una forma más directa y flexible de configurar el enrutamiento en aplicaciones React, reemplazando el uso del componente tradicional BrowserRouter
.
Configuración básica
El uso de createBrowserRouter
implica definir las rutas y su configuración directamente en el archivo de enrutamiento, lo que facilita la gestión y lectura del código. Aquí hay un ejemplo básico de cómo configurar un enrutador con createBrowserRouter
:
// router.jsx
import { createBrowserRouter } from 'react-router-dom';
import Layout from './pages/Layout/Layout';
import Home from './pages/Home/Home';
import About from './pages/About/About';
const router = createBrowserRouter([
{
element: <Layout />,
children: [
{
path: '/',
element: <Home />,
},
{
path: 'about',
element: <About />,
},
]
}
]);
export default router
// Layout.jsx
import { NavLink, Outlet } from "react-router-dom";
export default function Layout() {
return (
<>
<header>
<nav>
<NavLink to="/">Home</NavLink>
<NavLink to="/about">Perfil de usuario</NavLink>
</nav>
</header>
<Outlet />
</>
);
}
// main.jsx
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import { RouterProvider } from 'react-router-dom';
import router from './router';
createRoot(document.getElementById('root')).render(
<StrictMode>
<RouterProvider router={router} />
</StrictMode>,
)
Uso de
createBrowserRouter
en lugar deBrowserRouter
: AunqueBrowserRouter
sigue siendo funcional, se recomienda el uso decreateBrowserRouter
para una mayor flexibilidad y control.
Manejo de errores en rutas
La nueva versión incluye mejores mecanismos para manejar errores de enrutamiento, permitiendo definir rutas de error de manera más sencilla y clara. Esto se puede hacer directamente en la configuración de rutas:
// router.jsx
import { createBrowserRouter } from 'react-router-dom';
import Home from './pages/Home/Home';
import NotFound from './pages/NotFound/NotFound';
const router = createBrowserRouter([
{
path: '/',
element: <Home />,
errorElement: <NotFound />, // Elemento a renderizar en caso de error
},
// otras rutas...
]);
export default router
Data loaders y acciones
Una de las características más importantes de createBrowserRouter
es su capacidad para manejar datos y acciones de manera eficiente. Esto se logra a través de las propiedades loader
y action
, que permiten realizar operaciones asíncrona directamente en la definición de las rutas.
// router.jsx
import { createBrowserRouter } from 'react-router-dom';
import Home from './pages/Home/Home';
import Login, { loginAction } from './pages/Login/Login';
const router = createBrowserRouter([
{
path: '/',
element: <Home />,
loader: async () => {
const response = await fetch('https://jsonplaceholder.typicode.com/todos/1');
const todo = await response.json();
return todo;
},
},
{
path: 'login',
element: <Login />,
action: loginAction,
},
]);
export default router
// main.jsx
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import { RouterProvider } from 'react-router-dom';
import router from './router';
createRoot(document.getElementById('root')).render(
<StrictMode>
<RouterProvider router={router} />
</StrictMode>,
)
useLoaderData
y useActionData
: Nuevos hooks para acceder a los datos cargados por loaders y actions dentro de los componentes de la ruta.
Ejemplo usando useLoaderData
:
// Home.jsx
import { useLoaderData } from "react-router-dom";
export default function Home() {
const data = useLoaderData();
return (
<div>
<h1>Home Page</h1>
<ul>
<li>ID: <span>{data.id}</span></li>
<li>User ID: <span>{data.userId}</span></li>
<li>Title: <span>{data.title}</span></li>
<li>Completed: <span>{data.completed}</span></li>
</ul>
</div>
)
}
Ejemplo de useActionData
:
// Login.jsx
import { Form, redirect, useActionData, } from "react-router-dom";
export default function Login() {
const errors = useActionData();
return (
<div>
<h1>Inicio de sesión</h1>
<Form method="post">
<label>
Email
<input type="text" name="email" />
{errors?.email && <small>{errors.email}</small>}
</label>
<br />
<label>
Password
<input type="password" name="password" />
{errors?.password && <small>{errors.password}</small>}
</label>
<br />
<button type="submit">Sign up</button>
</Form>
</div>
);
}
export async function loginAction({ request }) {
const formData = await request.formData();
const email = formData.get("email");
const password = formData.get("password");
const errors = {};
// validate the fields
if (typeof email !== "string" || !email.includes("@")) {
errors.email =
"That doesn't look like an email address";
}
if (typeof password !== "string" || password.length < 6) {
errors.password = "Password must be > 6 characters";
}
// return data if we have errors
if (Object.keys(errors).length) {
return errors;
}
// otherwise login the user and redirect
console.log("Login successful");
return redirect("/");
}
Definición de rutas en JSX
La función createRoutesFromElements
permite definir rutas directamente en JSX, lo que hace que la definición de rutas sea más declarativa y fácil de entender.
// router.jsx
import { createBrowserRouter, createRoutesFromElements, Route } from 'react-router-dom';
import Home from './pages/Home/Home';
import About from './pages/About/About';
const router = createBrowserRouter(
createRoutesFromElements(
<>
<Route path="/" element={<Home />} />
<Route path="about" element={<About />} />
</>
)
);
export default router
// main.jsx
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import { RouterProvider } from 'react-router-dom';
import router from './router';
createRoot(document.getElementById('root')).render(
<StrictMode>
<RouterProvider router={router} />
</StrictMode>,
)
Carga diferida de componentes
React Router v6+ facilita la integración con Suspense
y lazy
para cargar componentes de manera diferida, mejorando el rendimiento de la aplicación. Por ejemplo:
// router.jsx
import { lazy, Suspense } from 'react';
import { createBrowserRouter } from 'react-router-dom';
const Home = lazy(() => import('./pages/Home/Home'));
const About = lazy(() => import('./pages/About/About'));
const NotFound = lazy(() => import('./pages/NotFound/NotFound'));
const router = createBrowserRouter([
{
path: '/',
element: (
<Suspense fallback={<div>Loading...</div>}>
<Home />
</Suspense>
),
},
{
path: 'about',
element: (
<Suspense fallback={<div>Loading...</div>}>
<About />
</Suspense>
),
},
{
path: '*',
element: (
<Suspense fallback={<div>Loading...</div>}>
<NotFound />
</Suspense>
),
},
]);
export default router
Diferencias entre BrowserRouter y createBrowserRouter
En React Router v6+, tanto BrowserRouter
como createBrowserRouter
son utilizados para manejar el enrutamiento en aplicaciones React, pero presentan diferencias significativas en su configuración y capacidades.
BrowserRouter
es el componente tradicional que envuelve la aplicación y permite la navegación mediante el historial del navegador. Su configuración suele ser más sencilla y directa, pero menos flexible en comparación con createBrowserRouter
.
// App.jsx
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import Home from './pages/Home/Home';
import About from './pages/About/About';
export default function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<Home />} />
<Route path="about" element={<About />} />
</Routes>
</BrowserRouter>
);
}
Por otro lado, createBrowserRouter
es un método introducido en React Router v6+ que proporciona una configuración más flexible y directa. Permite definir rutas y su configuración en un solo lugar, ofreciendo capacidades avanzadas como loaders, actions y manejo de errores directamente en las rutas.
// router.jsx
import { createBrowserRouter } from 'react-router-dom';
import Home from './pages/Home/Home';
import Login, { loginAction } from './pages/Login/Login';
import ErrorPage from './pages/ErrorPage/ErrorPage';
const router = createBrowserRouter([
{
path: '/',
element: <Home />,
errorElement: <ErrorPage />,
loader: async () => {
const response = await fetch('https://jsonplaceholder.typicode.com/todos/1');
const todo = await response.json();
return todo;
},
},
{
path: 'login',
element: <Login />,
errorElement: <ErrorPage />,
action: loginAction,
},
]);
export default router
// main.jsx
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import { RouterProvider } from 'react-router-dom';
import router from './router';
createRoot(document.getElementById('root')).render(
<StrictMode>
<RouterProvider router={router} />
</StrictMode>,
)
Las principales diferencias entre BrowserRouter
y createBrowserRouter
son los siguientes:
Configuración de rutas: BrowserRouter
utiliza el componente Routes
y Route
para definir las rutas dentro de la estructura JSX, mientras que createBrowserRouter
permite definir rutas directamente en una configuración de objetos.
Loaders y actions: createBrowserRouter
proporciona soporte nativo para loaders y actions, permitiendo operaciones asíncronas y manejo de datos directamente en la definición de rutas. BrowserRouter
no tiene esta funcionalidad integrada y requiere soluciones adicionales para manejar datos asíncronos.
Manejo de errores: createBrowserRouter
permite definir componentes de error específicos para manejar errores en las rutas mediante la propiedad errorElement
. Con BrowserRouter
, el manejo de errores suele ser más manual y menos integrado.
Flexibilidad y mantenibilidad: createBrowserRouter
ofrece una configuración más centralizada y declarativa, lo que puede mejorar la mantenibilidad y la claridad del código en aplicaciones grandes. BrowserRouter
sigue siendo adecuado para aplicaciones más simples o donde se prefiera una configuración más directa.
Estos puntos destacan cómo createBrowserRouter
proporciona una mayor flexibilidad y capacidades avanzadas en comparación con BrowserRouter
, haciéndolo una opción preferida en proyectos que requieren una gestión más compleja del enrutamiento y los datos.

Alan Sastre
Ingeniero de Software y formador, CEO en CertiDevs
Ingeniero de software especializado en Full Stack y en Inteligencia Artificial. Como CEO de CertiDevs, React es una de sus áreas de expertise. Con más de 15 años programando, 6K seguidores en LinkedIn y experiencia como formador, Alan se dedica a crear contenido educativo de calidad para desarrolladores de todos los niveles.
Más tutoriales de React
Explora más contenido relacionado con React y continúa aprendiendo con nuestros tutoriales gratuitos.
Aprendizajes de esta lección
- Comprender las diferencias entre
BrowserRouter
ycreateBrowserRouter
. - Implementar rutas con
createBrowserRouter
. - Manejar errores de enrutamiento con
createBrowserRouter
. - Utilizar
loader
yaction
para operaciones asíncrona. - Definir rutas en JSX con
createRoutesFromElements
. - Integrar
Suspense
ylazy
para carga diferida de componentes.