Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
December 16, 2021 01:02 pm GMT

React - Introduction to react router v6

Installation

After creating our react app we have to install the react router v6 library to our project using npm:

npm install react-router-dom@6

And import the BrowserRouter to our index.js:

import React from "react";import ReactDOM from "react-dom";import "./index.css";import App from "./App";import { BrowserRouter } from "react-router-dom";ReactDOM.render(  <BrowserRouter>    <App />  </BrowserRouter>,  document.getElementById("root"));

Now our react application can now response to different urls.

Creating links

To create links on react we could try sing the regular html links and that would lets us navigate to different urls defined in our application but if you try you will realize that each time you click on a link you are reloading the whole page and that's something we dont do on react as react works as single page application.

Instead we use Link from the react-router-dom package we installed earlier.

import { Link } from "react-router-dom";import "./App.css";const App = () => { return <Link to="/hotels">Hotels</Link>;};

Image description

It's discrete but there's a link at the top left of our page but when clicking the page it doesn't get reloaded :) but its not showing nothing new :( thou it changes the current url :)

Defining routes

On my react example app Ive created 2 pages:

  • Hotels list.

  • Form to add new hotels to the list.

So I need two routes. One for each page.

Image description

Image description
(follow me for more design tips )

To create a those new routes that matches I will make use of Routes and Route from the react-router package.

import { useState } from "react";import { Route, Routes } from "react-router";import classes from "./app.module.css";import Nav from "./components/Nav";import Form from "./pages/Form";import Hotels from "./pages/Hotels";const App = () => {  const hotelsArray = [    {      name: "Hotel Barcelona",      rooms: 5,      rating: 8,    },    {      name: "Hotel Paris",      rooms: 41,      rating: 9,    },    {      name: "Hotel Munich",      rooms: 14,      rating: 10,    },  ];  const [hotels, setHotels] = useState(hotelsArray);  const newHotelHandler = (hotel) => {    setHotels((prevState) => [...prevState, hotel]);  };  return (    <>      <Nav />      <div className={classes.container}>        <Routes>          <Route path="/hotels" element={<Hotels hotels={hotels} />} />        </Routes>        <Routes>          <Route path="/new" element={<Form onSubmit={newHotelHandler} />} />        </Routes>      </div>    </>  );};export default App;

On the app I have the hardcoded list of initial hotels to set is as default state and the functions that adds new hotels and updates the state.

To navigate through the pages Ive created a new component called nav that contains all the Links:

import classes from "./Nav.module.css";import { Link } from "react-router-dom";const Nav = () => {  return (    <div className={classes.nav}>      <div className={classes.nav__container}>        <Link style={{textDecoration: 'none', color: 'white'}} to="/hotels">Hotels</Link>        <Link style={{textDecoration: 'none', color: 'white'}} to="/new">Add new</Link>      </div>    </div>  );};export default Nav;

This way now I have a set of urls to navigate on my hotels app:

Image description

Params on url

Now I have a list of nice hotels and a form to add new ones but what if I want to check one hotel details. To do that It would be nice to have a parameterized url where to pass the hotel id so my react app can retrieve the hotel details.

To do it we have to define a new route in our app.js . I want that url to be /hotels/hotelID so my new route will be defined like this:

<Routes>    <Route path="/hotels/:hotelId" element={<Details hotels={hotels} />} />        </Routes>

And on a new page I will:

  1. Read the hotel id from url.
  2. Get the hotel details (actually what I will do is get the hotel position on the hotels list).

Reading the hotel id from the url

To do that we need to import the useParams hook from the react-router-dompackage and read the params:

import { useParams } from "react-router-dom";const Details = () => {  const params = useParams();  return <h1>{params.hotelId}</h1>;};export default Details;

Image description

The params are the ones we've defined in the route path.

Getting the hotel details

import classes from "./Details.module.css";import { Link, useParams } from "react-router-dom";const Details = ({ hotels }) => {  const params = useParams();  const hotel = hotels[params.hotelId];  return (    <div className={classes.container}>      <h1>Hotel: {hotel.name}</h1>      <h2>Rooms: {hotel.rooms}</h2>      <h3>Rating: {hotel.rating}/10</h3>      <Link to="/hotels">        <button className={classes.container__save}>Hotels</button>      </Link>    </div>  );};export default Details;

To access to this url I've updated the hotels list component so each hotel now has a Link:
import { Link } from "react-router-dom";
import classes from "./Hotels.module.css";

const Hotels = ({ hotels }) => {  return (    <div className={classes.container}>      {hotels.map((hotel, key) => {        return (          <Link to={`/hotels/${key}`} style={{textDecoration: 'none', color: 'black'}}>            <div key={key} className={classes.element}>              <h1>{hotel.name}</h1>              <h2>Rooms: {hotel.rooms}</h2>              <h3>Rating: {hotel.rating}/10</h3>            </div>          </Link>        );      })}    </div>  );};export default Hotels;


javascript

Navigate programmatically

Sometimes we may need to navigate our users programmatically. If you try the form to add new hotels to the list you will realize that after creating a new hotel you have to manually navigate to the hotels list with the top nav. It works but we can do it better.

At the Form.js component we have to import the useNavigate hook from the react-router-dom package.

import { useState } from "react";import { useNavigate } from "react-router-dom";import classes from "./Form.module.css";const Form = ({ onSubmit }) => {  const navigate = useNavigate();  const [name, setName] = useState("");  const [rooms, setRooms] = useState(0);  const [rating, setRating] = useState(0);  const nameHandler = (event) => {    setName(event.target.value);  };  const roomsHandler = (event) => {    setRooms(event.target.value);  };  const ratingHandler = (event) => {    setRating(event.target.value);  };  const onSubmitHandler = () => {      onSubmit({name: name, rooms: rooms, rating: rating});      // After saving the hotel redirect the user to the hotels list      navigate('/hotels')  }  return (    <div className={classes.container}>      <div className={classes.container__field}>        <label>Hotel Name</label>        <input onChange={nameHandler} type="text" />      </div>      <div className={classes.container__field}>        <label>Rooms</label>        <input onChange={roomsHandler} type="number" min="1" max="99" />      </div>      <div className={classes.container__field}>        <label>Rating</label>        <input onChange={ratingHandler} type="number" min="1" max="10" />      </div>      <button onClick={onSubmitHandler} className={classes.container__save}>Save</button>    </div>  );};export default Form;

Nested routes

Our hotels app now works better but theres another thing we could improve. There's two routes where one is child of another: /hotels and /hotels/:hotelId.

On this example they are just two routes but on larger apps this can be annoying so let's nested instead using relative paths:

import { useState } from "react";import { Route, Routes } from "react-router";import classes from "./app.module.css";import Nav from "./components/Nav";import Details from "./pages/Details";import Form from "./pages/Form";import Hotels from "./pages/Hotels";const App = () => {  const hotelsArray = [    {      name: "Hotel Barcelona",      rooms: 5,      rating: 8,    },    {      name: "Hotel Paris",      rooms: 41,      rating: 9,    },    {      name: "Hotel Munich",      rooms: 14,      rating: 10,    },  ];  const [hotels, setHotels] = useState(hotelsArray);  const newHotelHandler = (hotel) => {    setHotels((prevState) => [...prevState, hotel]);  };  return (    <>      <Nav />      <div className={classes.container}>        <Routes>          <Route path="/hotels">            <Route path="" element={<Hotels hotels={hotels} />} />            <Route path=":hotelId" element={<Details hotels={hotels} />} />          </Route>        </Routes>        <Routes>          <Route path="/new" element={<Form onSubmit={newHotelHandler} />} />        </Routes>      </div>    </>  );};export default App;

Here's link to github where you can download the project and try it and there's a demo


Original Link: https://dev.to/josec/rect-introduction-to-react-router-v6-2560

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To