React-Router es una biblioteca React popular que se usa mucho para el enrutamiento del lado del cliente y ofrece enrutamiento de una sola página. Proporciona varias API de componentes (como ruta, enlace, interruptor, etc.) que puede usar en su aplicación React para representar diferentes componentes según los nombres de ruta de URL en una sola página.
Requisito previo: Lea primero los artículos a continuación, si aún no está familiarizado con React Router
Nota: debe tener React >= 16.8 instalado en su dispositivo; de lo contrario, los ganchos no funcionarán.
Hooks Of React Router 5: React Router 5 ofrece 4 hooks que puede usar en sus aplicaciones de reacción:
- useHistory
- useParams
- useUbicación
- usarRouteMatch
Discutiremos todos los ganchos en detalle con ejemplos adecuados:
1. useHistory: este es uno de los ganchos más populares proporcionados por React Router. Le permite acceder a la instancia de historial utilizada por React Router. Usando la instancia de historial, puede redirigir a los usuarios a otra página. La instancia de historial creada por React Router usa una pila (llamada «Pila de historial»), que almacena todas las entradas que el usuario ha visitado.
Sintaxis :
import { useHistory } from "react-router-dom"; // Inside a functional component export default function SomeComponent(props){ // The useHistory() hook returns the history // object used by React Router const history = useHistory(); }
El objeto de historial devuelto por useHistory() tiene varias propiedades y métodos.
Propiedades:
- longitud: Devuelve un Número. El número de entradas en la pila de historial
- action: Devuelve una string que representa la acción actual (PUSH, REPLACE o POP).
- ubicación: Devuelve un objeto que representa la ubicación actual. Puede tener las siguientes propiedades:
- pathname: una string que contiene la ruta de la URL
- búsqueda: una string que contiene la string de consulta de URL
- hash: una string que contiene el fragmento hash de URL
- estado: un objeto que contiene un estado específico de la ubicación que se proporcionó, por ejemplo, empujar (ruta, estado) cuando esta ubicación se colocó en la pila. Solo disponible en el navegador y el historial de memoria.
Métodos:
- push(ruta, [estado]): empuja una nueva entrada a la pila de historial. Útil para redirigir a los usuarios a la página.
- replace (ruta, [estado]): reemplaza la entrada actual en la pila de historial
- go(n): Mueve el puntero en la pila de historial por n entradas
- goBack(): Equivalente a go(-1).
- goForward(): Equivalente a go(1).
- block(prompt): Bloquea la navegación. Toma una devolución de llamada como parámetro y la invoca después de que se bloquea la navegación. Más útil cuando desea confirmar primero si el usuario realmente desea abandonar la página.
Ejemplo: Supongamos que tenemos un proyecto React creado usando «create-react-app» con la siguiente estructura de proyecto.
Estructura del proyecto:
react-router-hooks-tutorial/ |--public/ |--src/ | |--components/ | | |-->Home.js | | |-->ContactUs.js | | |-->AboutUs.js | | |-->LogIn.js | | |-->Profile.js | |-->App.js | |-->App.css | |-->index.js | |-->index.css | |-->... (other files) |-- ...(other files)
Supongamos que, dentro de «LogIn.js», tenemos un componente «LogIn» que representa la página de inicio de sesión. El componente LogIn muestra dos campos de entrada, uno para el nombre de usuario y otro para la contraseña. Cuando el usuario hace clic en el botón de inicio de sesión, queremos autenticar al usuario y redirigirlo a su página de perfil.
LogIn.js
import { useHistory } from "react-router-dom"; import { useState } from "react"; // A function that authenticates the users function authenticateUser(userName, password) { // Some code to authenticate the user } // Hooks must be used inside a functional component export default function Login(props) { //Creating a state variable const [userName, setUserName] = useState(""); const [password, setPassword] = useState(""); // Accessing the history instance created by React const history = useHistory(); // Handle the user clicks the login button const handleClick = () => { // Authenticate the user authenticateUser(userName, password); // When the authentication is done // Redirect the user to the `/profile/${userName}` page // the below code adds the `/profile/${userName}` page // to the history stack. history.push(`/profile/${userName}`); }; return ( <div> <input type="text" value={userName} onChange={(e) => { setUserName(e.target.value); }} required /> <input type="text" value={password} onChange={(e) => { setPassword(e.target.value); }} required /> <button type="submit" onClick={handleClick}> {" "} Log In{" "} </button> </div> ); }
Producción:
Verifique el componente de inicio de sesión con cuidado, la función » handleClick » toma el nombre de usuario y la contraseña y llama a la función » autenticar usuario» que de alguna manera autentica al usuario. Cuando se realiza la autenticación, queremos redirigir al usuario a la página «perfil/John» (supongamos que el nombre de usuario es «John»). Eso es lo que hace la última línea de la función handleClick. El gancho “useHistory()” devuelve la instancia de historial creada por React Router, y history.push(“/profile/John”) agrega la URL dada a la pila de historial, lo que resulta en la redirección del usuario a la ruta de URL dada. De manera similar, puede usar otros métodos y parámetros del objeto de historial según sus necesidades.
Consulte el siguiente enlace para ver cómo funciona la redirección a una URL dinámica.
2. useParams: este gancho devuelve un objeto que consta de todos los parámetros en la URL.
Sintaxis:
import { useParams } from "react-router-dom"; // Inside a functional component export default function SomeComponent(props){ const params = useParams(); }
Estos parámetros de URL se definen en la URL de ruta. Por ejemplo,
<Route path="/profile/:userName" component={Profile} />
Los dos puntos («:») después de «/perfil/» especifica que «nombre de usuario» es en realidad una variable o parámetro que es dinámico. Por ejemplo, en la url “/perfil/johndoe”, “johndoe” es el valor del parámetro “userName”. Entonces, en este caso, el objeto devuelto por useParams() es:
{ userName: "johndoe" }
Ejemplo: después del inicio de sesión, queremos que nuestro usuario sea redirigido a la URL «perfil/nombre de usuario». El nombre de usuario depende del nombre de pila del usuario. Por lo tanto, debemos establecer la ruta de la URL dinámicamente en función del nombre de usuario proporcionado por el usuario. Esto es fácil de hacer, necesitamos actualizar un poco el archivo App.js.
App.js
import { Route, Switch } from "react-router-dom"; import Home from "./components/Home"; import ContactUs from "./components/ContactUs"; import LogIn from "./components/LogIn"; import AboutUs from "./components/AboutUs"; import Profile from "./components/Profile"; export default function App() { return ( <div className="App"> <Switch> <Route path="/" exact> <Home someProps={{ id: 54545454 }} /> </Route> <Route path="/about"> <AboutUs /> </Route> <Route path="/contact-us"> <ContactUs /> </Route> <Route path="/log-in"> <LogIn /> </Route> {/* userName is now a variable */} <Route path="/profile/:userName"> <Profile /> </Route> </Switch> </div> ); }
Profile.js
import {useParams} from "react-router-dom"; export default function Profile( props ) { // useParams() returns an object of the parameters // defined in the url of the page // For example, the path given in the Route component // consists of an "userName" parameter // in this form ---> "/profile/:userName" const { userName } = useParams(); return ( <div> <h1> Profile of { userName }</h1> <p> This is the profile page of { userName }</p> </div> ); }
Salida: ahora, si ahora va a la página de inicio de sesión y hace clic en el botón de inicio de sesión con el nombre de usuario «John», será redirigido a la página «perfil/john».
3. useLocation: este enlace devuelve el objeto de ubicación utilizado por el enrutador de reacción. Este objeto representa la URL actual y es inmutable. Cada vez que cambia la URL, el gancho useLocation() devuelve un objeto de ubicación recién actualizado. Parte de su uso incluye extraer los parámetros de consulta de la URL y hacer algo en función de los parámetros de consulta. La propiedad de «búsqueda» del objeto de ubicación devuelve una string que contiene la parte de consulta de la URL.
Sintaxis:
import { useLocation } from "react-router-dom"; // Inside functional component export default function SomeComponent(props){ const location = useLocation(); }
Nota: history.location también representa la ubicación actual, pero es mutable, por otro lado, la ubicación devuelta por useLocation() es inmutable. Por lo tanto, si desea utilizar la instancia de ubicación, se recomienda utilizar el gancho useLocation().
Ejemplo: useLocation() es muy útil para obtener y usar los parámetros de consulta definidos en la URL. En el siguiente código, hemos utilizado el enlace useLocation para acceder a los parámetros de consulta. Luego lo analizamos usando el constructor URLSearchParams.
Profile.js
import { useLocation } from "react-router-dom"; export default function Profile(props) { const location = useLocation(); // location.search returns a string containing all // the query parameters. // Suppose the URL is "some-website.com/profile?id=12454812" // then location.search contains "?id=12454812" // Now you can use the URLSearchParams API so that you can // extract the query params and their values const searchParams = new URLSearchParams(location.search); return ( <div> { // Do something depending on the id value searchParams.get("id") // returns "12454812" } </div> ); }
Producción :
4. useRouteMatch: devuelve un objeto de coincidencia que contiene toda la información, como la coincidencia de la URL actual con la ruta de la ruta.
Propiedades:
- params: Este es un objeto que contiene la parte variable de la URL.
- isExact: este es un valor booleano que indica si la URL completa coincidió con la ruta del enrutador dada.
- ruta: una string que contiene el patrón de ruta.
- URL: una string que contiene la parte coincidente de la URL. Se puede utilizar para <Link />s y <Route />s anidados.
Sintaxis:
import { useRouteMatch } from "react-router-dom"; // Inside functional component export default function SomeComponent(props) { const match = useRouteMatch(); }
Ejemplo: el enlace useRouterMatch se puede usar para crear rutas y enlaces anidados. El siguiente código muestra la página de perfil del usuario cuando la ruta de la URL actual coincide por completo con la ruta de la ruta dada; de lo contrario, muestra otra ruta que muestra la página de seguidores del usuario cuando la ruta de la URL actual es «perfil/:nombre de usuario/seguidores».
Profile.js
import { Link, Route, useParams, useRouteMatch } from "react-router-dom"; export default function Profile(props) { // useParams() returns an object of the parameters // defined in the url of the page // For example, the path given in the Route component // consists of an "userName" parameter // in this form ---> "/profile/:userName" const { userName } = useParams(); const match = useRouteMatch(); return ( <div> {match.isExact ? ( <div> <h1> Profile of {userName}</h1> <p> This is the profile page of {userName}</p> <Link to={`${match.url}/followers`}> Followers </Link> </div> ) : ( <Route path={`${match.url}/followers`}> <div>My followers</div> </Route> )} </div> ); }
Producción:
Si hace clic en el enlace del seguidor, será redirigido a la página “/perfil/Juan/seguidores”, y como la ruta URL completa “perfil/Juan/seguidores” no coincide con la ruta de ruta dada, es decir, “perfil/;nombre de usuario” , por lo que se representa el elemento div dentro del componente Ruta.
Recuerde que debe tener React 16.8 o superior para usar estos enlaces de enrutador de reacción. Además, no olvide usarlos dentro de componentes funcionales.
Razón para usar los ganchos de enrutador React
Antes de React Router 5: de forma predeterminada, al usar el accesorio del componente (<Route component={} />), el enrutador React pasa tres accesorios (coincidencia, ubicación, historial) al componente que representa la ruta. Eso significa que, si, por alguna razón, desea acceder al historial o la instancia de ubicación utilizada por el enrutador React, puede acceder a él a través de los accesorios predeterminados.
About.js
import {useLocation} from "react-router-dom"; export default function ( props ){ // Accessing the location and history // through the props const location = props.location; const history = props.history; return( <div> // Some content </div> ); }
Pero si pasa sus accesorios personalizados a sus componentes, los accesorios predeterminados serán anulados por sus accesorios personalizados. Como resultado, no tendrá más acceso al objeto de historial creado por React Router. Y antes de React Router 5, no había otra forma que usar el accesorio de renderizado (<Router render={} />) para pasar explícitamente la ubicación, la coincidencia y la instancia del historial como accesorios.
App.js
import "./styles.css"; import { Route, Switch } from "react-router-dom"; import About from "./components/About"; export default function App() { return ( <div className="App"> <Switch> // In this case, you have to use render // instead of component and explicitly // pass the props <Route path="/about" render={({ match, location, history }) => ( <About match={match} location={location} history={history} someProps={{ id: 21254 }} /> )} /> </Switch> </div> ); }
Con React Router 5 Hooks: ahora con React Router 5, puede pasar fácilmente sus accesorios personalizados al componente de renderizado.
App.js
import "./styles.css"; import { Route, Switch } from "react-router-dom"; import Home from "./components/Home"; import ContactUs from "./components/ContactUs"; import LogIn from "./components/LogIn"; import AboutUs from "./components/AboutUs"; export default function App() { return ( <div className="App"> <Switch> <Route path="/" exact> <Home someProps={{ id: 54545454 }} /> </Route> <Route path="/about"> <AboutUs /> </Route> <Route path="/contact-us"> <ContactUs /> </Route> <Route path="/log-in"> <LogIn /> </Route> </Switch> </div> ); }
Aunque en este caso también esos tres accesorios (coincidencia, ubicación, historial) no superan los componentes renderizados automáticamente, ahora podemos usar los ganchos proporcionados por React Router 5, y ya no necesitamos pensar en los accesorios. Puede acceder directamente al objeto de historial usando el enlace useHistory, el objeto de ubicación con el enlace useLocation y haga coincidir el objeto con el enlace useRouteMatch, y no tiene que pasar explícitamente los accesorios a los componentes.
Home.js
import { useHistory, useLocation, useParams, useRouteMatch, } from "react-router-dom"; export default function Home(props) { // Access the history object with useHistory() const history = useHistory(); // Access the location object with useLocation const location = useLocation(); // Access the match object with useRouteMatch const match = useRouteMatch(); // Extract the URL parameters with useParams const params = useParams(); return <div>{/* Some code */}</div>; }