React Router
Applications have more than one page…
Fulvio Corno
Luigi De Russis
                                Applicazioni Web I - Web Applications I - 2023/2024
Outline
• Objective and problems
• A Solution, the React way: React Router
                                                                                 2
                           Applicazioni Web I - Web Applications I - 2023/2024
                                                                                            Full Stack React, chapter “Routing”
                                                                                            React Handbook, chapter “React Router”
Multi-page Single Page Applications
OBJECTIVES AND PROBLEMS
                                                                                                                                     3
                                      Applicazioni Web I - Web Applications I - 2023/2024
Supporting Complex Web Applications
• Switching between many different page layouts
• Managing the flow of navigation across a set of “pages”
• Maintaining the default web navigation conventions (back, forward,
  bookmarks, …)
• Allowing URLs to convey information
• Avoiding to re-load KBs of JavaScript at every page change
• Keeping the state across page changes
• …
                                                                                 4
                           Applicazioni Web I - Web Applications I - 2023/2024
Example
                                                                              • Different layout
                                                                                and contents
          /                                    /profilename                   • Some common
                                                                                parts
                                                                              • No “page reload”
                                                                              • URL changes
                                                                                accordingly
/pages/?category=your
                                                  /pagename
        _pages
                                                                                               5
                        Applicazioni Web I - Web Applications I - 2023/2024
Some Use Cases
•   Main list / detail view
•   Logged / Unlogged pages
•   Sidebar navigation
•   Modal content
•   Main Contents vs. User Profile vs. Setting vs. …
                                                                                    6
                              Applicazioni Web I - Web Applications I - 2023/2024
Using URLs for Navigation State
• URLs determine the type of the page or the section of                            Example URLs on
  the website                                                                      facebook.com:
   – Changing page ⇆ Changing the URL                                              /
                                                                                   /profile.name
• URLs also embed information about the item IDs,
                                                                                   /profile.name
  referrers, categories, filters, etc.                                             /posts/12341232124
• URLs can be shared/saved/bookmarked, and they are                                22123
                                                                                   /pagename
  sufficient for rebuilding the whole exact page
                                                                                   /pages/?category=y
   – Deep Linking                                                                  our_pages
• Back and Forward buttons navigate the URL history
                                                                                                     7
                             Applicazioni Web I - Web Applications I - 2023/2024
Using URLs for Navigation State
• URLs determine the type of the page or the section of                                      Example URLs on
  the website                                                                                facebook.com:
    – Changing page ⇆ Changing the URL                                                       /
                                                                                             /profile.name
• URLs also embed information about the item IDs,
                                                                                             /profile.name
  referrers, categories,       filters, etc
              Special configuration:
                                                                                             /posts/12341232124
• URLs can be ➢ shared/saved/bookmarked,                     andreturn
                 With any URL, the React application will always   theythe are               22123
                 same page (index.html/index.js) that will load and                          /pagename
  sufficient formount
                  rebuilding       the whole exact page
                        the same App
                                                                                             /pages/?category=y
    – Deep Linking                                                                           our_pages
                 ➢ The URL content is then queried by the App to customize
• Back and      Forward    buttons navigate the URL history
                   the render
                                                                                                               8
                                       Applicazioni Web I - Web Applications I - 2023/2024
                                                                               https://reactrouter.com/
                                                                               https://flaviocopes.com/react-router/
                                                                               https://www.robinwieruch.de/react-router/
                                                                               Full Stack React, chapter “Routing”
                                                                               React Handbook, chapter “React Router”
React as a REST Client
THE REACT ROUTER
                                                                                                                           9
                         Applicazioni Web I - Web Applications I - 2023/2024
React Router
• The problems associated with multi-page navigation and URL
  management are usually handled by router libraries
• A JavaScript Router manages
   – Modifying the location of the app (the URL)
   – Determining what React components to render at a given location
• In principle, whenever the user clicks on a new URL
   – We prevent the browser from fetching the next page
   – We instruct the React app to switch in & out components
                                                                                    10
                              Applicazioni Web I - Web Applications I - 2023/2024
React Router
• React does not contain a specific router functionality
   – Different router libraries are available
   – A commonly adopted one is react-router                                             https://reactrouter.com/
      • Current version 6.4                                                             https://github.com/remix-
                                                                                             run/react-router
   – npm install react-router-dom
      • Will also install react-router as a dependency
                                                                                                                   11
                                  Applicazioni Web I - Web Applications I - 2023/2024
Features
• Connects React app navigation with the browser’s native navigation
  features
• Selectively shows components according to the current routes
   – Rules matching URL fragments
• Easy to integrate and understand; it uses normal React components
   – Links to new pages are handled by <Link>, <NavLink>, and <Navigate>
   – To determine what must be rendered we use <Route> and <Routes>
   – Defines hooks useNavigate, useParams, useSearchParams
• The whole application is wrapped in a <RouterProvider> container
                                                                                   12
                             Applicazioni Web I - Web Applications I - 2023/2024
 Overview of React-Router
<RouterProvider>                                                        <RouterProvider >
                                                 '/about'
                                                                           <Routes>
<Link to='/'>Home</Link>                                                      <Route path="/">
<Link to='/about'>About</Link>                                                   element={<Home />} />
<Link to='/dashboard'>Dashboard</Link>                                        <Route path="/about">
                                                                                 element={<About />} />
                                                                              <Route path="/dashboard">
                                                                                 element={<Dashboard />} />
</RouterProvider >                                                         </Routes>
                                                                        </RouterProvider >
                                                                                                              13
                                Applicazioni Web I - Web Applications I - 2023/2024
Routers
• Routers can be created as functions or components
• Routers’ functions are quite new in React Router (since version 6.4)
• We will use the new Router creation functions in the course
   – Also called ‘data routers’ for their additional
     functionality (not used in the course)
                                                                                       https://reactrouter.com/en/main/routers/picking-a-router
                                                                                                                                                  14
                                 Applicazioni Web I - Web Applications I - 2023/2024
Types of routers
• createBrowserRouter uses normal URLs and the HTML5 Location API
  – Recommended for modern browsers
  – Requires some server configuration
  – import { createBrowserRouter, RouterProvider } from 'react-
    router-dom' ;
• createHashRouter uses ‘#’ in the URL
  – Compatible with older browsers
  – Requires no config on the server
  – Not recommended, unless for compatibility reasons
                                                                                   15
                             Applicazioni Web I - Web Applications I - 2023/2024
Types of routers
• createBrowserRouter uses normal URLs and the HTML5 Location API
   – Recommended for modern browsers
   – Requires some server configuration Not needed with the React Development Server.
   – import { createBrowserRouter, RouterProvider } from 'react-
                                        When served as a static bundle, all paths must be
     router-dom' ;                      mapped to index.html:
• createHashRouter uses ‘#’ in theapp.use(express.static('build'));
                                    URL
   – Compatible with older browsers    app.get('/*', function (req, res) {
   – Requires no config on the server    res.sendFile('build/index.html');
                                       });
   – Not recommended, unless for compatibility reasons
                                                          More on this -> next weeks!
                                                                                            16
                                 Applicazioni Web I - Web Applications I - 2023/2024
Creating the router -> edit main.jsx
import React from 'react'
import ReactDOM from 'react-dom/client'
import {
  createBrowserRouter,
  RouterProvider,
} from "react-router-dom";
import App from './App.jsx'
const router = createBrowserRouter([
  {                                                                                               Add the highlighted lines to
    path: "/*",                                                                                           main.jsx
    element:<App/>,
  },
]);
ReactDOM.createRoot(document.getElementById('root')).render(
  <React.StrictMode>
    <RouterProvider router={router} />
  </React.StrictMode>,
)
                                                                                                                                 17
                                            Applicazioni Web I - Web Applications I - 2023/2024
                                                                                https://reactrouter.com/en/main/route/route
Selective Render
• Alternative versions of a component content must be wrapped in
  <Routes>
   – Each alternative is represented by a Route
   – The route with the “most specific” match will be rendered
• Each <Route> specifies the URL path matching requirement
   – path = '/fragment' check if the URL matches the fragment
   – element = {<JSXelement/>} renders the specified JSX fragment if the
     path is the best match
                                <Routes>
                                    <Route path="/" element={<Home/>} />
                                    <Route path="/news" element={<NewsFeed/>} />
                                </Routes>
                                                                                                                          18
                               Applicazioni Web I - Web Applications I - 2023/2024
                                                                                          https://reactrouter.com/en/main/route/route
Route matching Methods
• path = string matched against the URL
• A path is made of different URL ‘segments’ (separated by /)
   – Static segment → e.g., users
   – Dynamic segment → e.g., :userId
   – Star segment → *
• Examples:
   –   /users/:userId
                                       If the Location URL matches more than
   –   /docs/*
                                       one route path, the most specific one is
   –   /                               selected
   –   /contact-us
• Options
   – caseSensitive: the match becomes case-sensitive (default: insensitive)
        • changing the default is not recommended
                                                                                                                                    19
                                         Applicazioni Web I - Web Applications I - 2023/2024
                                                                                https://reactrouter.com/en/main/route/route
Nesting Routes                                                                  https://reactrouter.com/en/main/components/
                                                                                outlet
• Routes may follow the layout hierarchy of the interface components
• It is possible to nest a <Route> inside another <Route> component
   – The paths will be concatenated
   – The parent <Routes> will browse, recursively, through all matching paths
   – All route elements in the best matching path will be rendered
• The matching children will be rendered inside the <Outlet> component
  in the parent’s render tree
   – <Outlet> specifies “where” the matching children should be rendered
   –    If you forget <Outlet>, the children will not display
                                                                                                                         20
                               Applicazioni Web I - Web Applications I - 2023/2024
Example
function App() {                                                     function Layout() {
  return (                                                             return (
     <div>                                                                <div>
       <h1>Basic Example</h1>                                               <nav>... main navigation menu ...<nav>
       <Routes>                                                             <hr />
         <Route path="/" element={<Layout />}>                              <Outlet />
            <Route path="about" element={<About />} />                    </div>
            <Route path="dashboard"                                    );
                 element={<Dashboard />} />                          }
         </Route>
       </Routes>
                                                                     function About() {
     </div>
                                                                       return (
  );
                                                                          <div>
}
                                                                            <h2>About</h2>
                                                                          </div>
                                                                       );
                                                                     }
                                                                                                                     21
                                         Applicazioni Web I - Web Applications I - 2023/2024
Special Routes (1/2)
• Index route
  – <Route index element={<Home />} />
  – A child route with no path that renders in the parent's outlet at the parent's URL
  – Use cases:
     • They match when a parent route matches but none of the other children match.
     • They are the default child route for a parent route.
     • They render when the user doesn’t have clicked one of the items in a navigation list yet.
                                                           https://reactrouter.com/en/main/start/concepts#index-routes
                                                                                                                   22
                                   Applicazioni Web I - Web Applications I - 2023/2024
Special Routes (2/2)
• Layout route
  – A route without path will always be matched
  – Useful to “wrap” with a common layout its children’s routes
• “No Match” route
  – Special case: path="*"
  – Will match only when no other routes do
                                                                                    23
                              Applicazioni Web I - Web Applications I - 2023/2024
Example
function App() {                                                                    function Layout() {
  return (                                                                            return (
     <div>                                                                               <div>
       <h1>Basic Example</h1>                                                              <nav>... main navigation menu ...<nav>
       <Routes>                                                                            <hr />
         <Route path="/" element={<Layout />}>                                             <Outlet />
            <Route index element={<Home />} />                                           </div>
            <Route path="about" element={<About />} />                                );
            <Route path="dashboard" element={<Dashboard />} />                      }
            <Route path="*" element={<NoMatch />} />
         </Route>
                                                                                    function Home() {
       </Routes>
                                                                                      return (
     </div>
                                                                                         <div>
  );
                                                                                           <h2>Home</h2>
}                                                                                        </div>
                                                                                      );
                                                                                    }
                                                                                                                                    24
                                         Applicazioni Web I - Web Applications I - 2023/2024
Navigation
• Changing the location URL will re-
  render the Router, and all Routes
  will be evaluated
• Two options:
   – <Link to= > creates a router-
     aware hyperlink (activated by user
     clicks)
   – useNavigate() returns a
     function to trigger navigation
     (useful inside event handlers)
                                                                                    25
                              Applicazioni Web I - Web Applications I - 2023/2024
Navigation
• Changing the location URL will re-                                                Warning
  render the Router, and all Routes
  will be evaluated                                          Never use a “plain hyperlink” <a>
• Two options:                                                Never use a “form submission”
   – <Link to= > creates a router-                               <form action='…'>
     aware hyperlink (activated by user
     clicks)
   – useNavigate() returns a                                      They will reload the whole
     function to trigger navigation                             application (and kill the current
     (useful inside event handlers)                                          state)
                                                                                                    26
                              Applicazioni Web I - Web Applications I - 2023/2024
Examples
function Home() {                                                    function Invoices() {
  return (                                                             const navigate = useNavigate();
     <div>                                                             return (
       <h1>Home</h1>                                                      <div>
       <nav>                                                                <NewInvoiceForm
         <Link to="/">Home</Link>                                              onSubmit={(event) => {
         {" "}                                                                    const newInvoice = create(event.target);
         <Link to="about">About</Link>                                            navigate(`/invoices/${newInvoice.id}`);
       </nav>                                                                  }}
     </div>                                                                 />
  );                                                                      </div>
}                                                                      );
                                                                     }
                                                All paths are relative,
                                               unless they start with /
                                                                                                                             27
                                         Applicazioni Web I - Web Applications I - 2023/2024
Active Navigation
• When creating menus or navigation elements, it is useful to see which
  item is the currently selected one
• <NavLink> behaves like <Link>, but knows whether it is “active”
   – It adds the “active” class to the rendered link (to be customized with CSS)
   – You may create a callback in className={} that receives the isActive status and
     decides which class to apply
   – You may create a callback in style={} that receives the isActive status and
     decides which CSS style(s) to apply
                                                                                       28
                               Applicazioni Web I - Web Applications I - 2023/2024
Dynamic Routes
• Routes may have parametric segments, with the :name syntax in the
  path specification
  – <Route path="/post/:id" element={<Post/>} />
  – The ‘id’ part will be available to the element through the useParams() hook
                                                                       function Post(props) {
 <Route
                                                                         const {id} = useParams();
   path="/post/:id"
                                                                         ...
   element={<Post/>} />
                                                                       }
                                                                                                     29
                             Applicazioni Web I - Web Applications I - 2023/2024
Dynamic Routes
• Routes may have parametric segments, with the :name syntax in the
  path specification
  – <Route path="/post/:id" element={<Post/>} />
  – The ‘id’ part will be available to the element through the useParams() hook
                  • useParams returns an object of
                     key/value pairs of the dynamic
                     params from the current URL that                          function Post(props) {
 <Route              were matched by the <Route path>                            const {id} = useParams();
   path="/post/:id"
                  • Child routes inherit all params from                         ...
   element={<Post/>} their
                      /> parent routes
                                                                               }
                                                                                                             30
                                     Applicazioni Web I - Web Applications I - 2023/2024
  Example
                        function App() {
                          return (
                             <Routes>
                               <Route
                                  path="/invoices/:invoiceId"
                                  element={<Invoice />}
                               />
                             </Routes>
                          );                                                                    Matches a URL like
                        }
                                                                                                /invoices/1234
function Invoice() {                                                  function Invoice() {
  let { invoiceId } = useParams();                                      let params = useParams();
  return <h1>Invoice {invoiceId}</h1>;                                  return <h1>Invoice {params.invoiceId}</h1>;
}                                                                     }
                                                                                                                      31
                                          Applicazioni Web I - Web Applications I - 2023/2024
Location State: Passing Information Among Pages
• When navigating, it is possible to                         const navigate = useNavigate() ;
  pass some information to the next                          // go to URL and send information
                                                             navigate( url, {state: userData} ) ;
  page, thanks to the
  location.state BOM attribute                               <Link to={url}
                                                                   state={userData} >
   – Alternative to dynamic URLs                                . . .
                                                             </Link>
• The value may be retrieved with
  useLocation() on the next page                             const location = useLocation();
                                                             const userData = location.state;
   – Beware: objects are serialized as
     strings, avoid passing ‘complex’ objects
     (e.g., dayjs objects)
                                                                                                    32
                                 Applicazioni Web I - Web Applications I - 2023/2024
Exploiting Search Parameters
• A URL may contain some “query                          let [searchParams, setSearchParams] =
                                                         useSearchParams();
  search parameters”                                     - searchParams is a URL.searchParams object
  – /products?sort=date&filter                           https://developer.mozilla.org/en-
                                                         US/docs/Web/API/URL/searchParams
    =valid                                               You may access each parameter with
• useSearchParams() allows                               searchParams.get('date')
                                                         searchParams.get('filter')
  you to read and modify the query
  string portion of the location                         - setSearchParams receives an object of { key: value }
                                                         pairs that will replace the current parameters
  – Returns the current version of the
    parameter, and a function to
    modify them
  – Behaves like useState
                                                                                                              33
                             Applicazioni Web I - Web Applications I - 2023/2024
Summary: react-router-dom
• Wrap main.jsx in                                  • Parameters
  createBrowserRouter                                       – useParams() for Dynamic Routes
• Routing and rendering:                                    – useSearchParams() for URL
  – <Routes>                                                  query strings (after “?”)
  – <Route path= element= />                                – useLocation() for retrieving
                                                              location state (set by navigate)
  – <Outlet/>
• Navigation:
  – <Link to= >…</Link>
  – <NavLink to= >…</NavLink>
  – useNavigate() or <Navigate>
                                                                                                 34
                        Applicazioni Web I - Web Applications I - 2023/2024
License
•   These slides are distributed under a Creative Commons license “Attribution-NonCommercial-
    ShareAlike 4.0 International (CC BY-NC-SA 4.0)”
•   You are free to:
     – Share — copy and redistribute the material in any medium or format
     – Adapt — remix, transform, and build upon the material
     – The licensor cannot revoke these freedoms as long as you follow the license terms.
•   Under the following terms:
     – Attribution — You must give appropriate credit, provide a link to the license, and indicate if changes were
       made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or
       your use.
     – NonCommercial — You may not use the material for commercial purposes.
     – ShareAlike — If you remix, transform, or build upon the material, you must distribute your contributions
       under the same license as the original.
     – No additional restrictions — You may not apply legal terms or technological measures that legally restrict
       others from doing anything the license permits.
•   https://creativecommons.org/licenses/by-nc-sa/4.0/
                                                                                                                     35
                                             Applicazioni Web I - Web Applications I - 2023/2024