Detailed Use of React Router V6

Detailed Use of React Router V6

  • Remix team released the first V6.0.0-beta in June 2020 The 0 version of React Router also indicates the official start of the V6 version. Compared with the V5 version, there are indeed many upgrades.
  • This article will explain in detail the use of React Router in combination with V6 features and how V5 upgrades V6.
  • (Version used: V6.0.2 stable version)

1, Basic usage

React -How to install the Router:

npm: npm install react-router-dom

yarn: yarn add react-router-dom

  • At present, the official has abandoned the original react router library since 5, and it is uniformly named as react router dom
usage method
  • React Router itself is a component in React development, so when it is used, it basically follows the relevant principles of component development. Here, create react app is used to create a basic demo project demonstration process.
  1. Create demo create react app my first react

Install the react router component

  1. Enable global routing mode

There are two common routing modes for global routing: HashRouter and BrowserRouter
HashRouter: The URL uses the hash(#) part to create a route, similar to www.example.com/#/ BrowserRouter: The URL uses real URL resources
Later articles will detail the principle and implementation of HashRouter. Here we use BrowserRouter to create routes

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { BrowserRouter } from 'react-router-dom';

ReactDOM.render(
 <React.StrictMode>
   <BrowserRouter>
     <App />
   </BrowserRouter>
 </React.StrictMode>,
 document.getElementById('root')
);

reportWebVitals();

In this way, we can access/access this component when yarn start or npm run start. You can run the specific effect yourself

  1. Routing function
    Common routing components and hooks in React Router V6. For others that are not commonly used, please refer to the official website
Component Nameeffectexplain
<Routers>A set of routesInstead of the original<Switch>, all sub routes are represented by the basic Router children
<Router>Basic routeRouter can be nested to solve the strict mode in the original V5. The differences between Router and V5 will be described in detail later
<Link>Navigation componentsJump to use in the actual page
<Outlet/>Adaptive Rendering ComponentsAutomatically select components according to the actual routing url
hooks Nameeffectexplain
useParamsReturn the current parameterRead parameters according to path
useNavigateReturn to the current routeReplace useHistory in the original V5
useOutletReturn the element generated according to the route
useLocationReturns the current location object
useRoutesLike Routers component, it is only used in js
useSearchParamsUsed to match the URL? Subsequent search parameters

App.js

  • Two components, Home and About, are created here, and then registered/and about respectively. There is a Link on each page for navigation

    import './App.css';
    import { Routes, Route, Link } from "react-router-dom"
    function App() {
     return (
       <div className="App">
         <header className="App-header">
           <Routes>
             <Route path="/" element={<Home />}></Route>
             <Route path="/about" element={<About />}></Route>
           </Routes>
         </header>
       </div>
     );
    }
    function Home() {
     return <div>
       <main>
         <h2>Welcome to the homepage</h2>
       </main>
       <nav>
         <Link to="/about">about</Link>
       </nav>
     </div>
    }
    function About() {
     return <div>
       <main>
         <h2>Welcome to the about page</h2>
       </main>
       <nav>
         <ol>
           <Link to="/">home</Link>
           <Link to="/about">about</Link>
         </ol>
    
       </nav>
     </div>
    }
    export default App;
    

    After operation

    So far, the simplest route demo is running normally.

  1. Nested Route

Nested routing is a major upgrade from previous versions in V6. Nested routing can be intelligently recognized

function App() {
 return (
   <Routes>
     <Route path="user" element={<Users />}>        
         <Route path=":id" element={<UserDetail />} />        
         <Route path="create" element={<NewUser />} />      
     </Route>
   </Routes>
 );
}

When accessing/user/123, the component tree will look like this

<App>
   <Users>
       <UserDetail/>
   </Users>
</App>

When accessing/user/create, the component tree will look like this

<App>
  <Users>
      <NewUser/>
  </Users>
</App>

If you are only modifying internal components, you can also use<Outlet/>to directly implement it, as shown below

function App() {
 return (
   <Routes>
     <Route path="user" element={<Users />}>        
         <Route path=":id" element={<UserDetail />} />        
         <Route path="create" element={<NewUser />} />      
     </Route>
   </Routes>
 );
}

function Users() {
 return (
   <div>
     <h1>Users</h1>
     <Outlet />
   </div>
 );
}
  1. index route

Method 1: The index attribute can be added to specify the default route when there are multiple sub routes in the nested route but it cannot confirm which sub route to render by default, or use useNavigate

import React, { useEffect } from 'react'
import { Routes, Route, useNavigate } from 'react-router-dom'
import Layout from '@/layout/Index'
import NotFound from '@/pages/NotFound'
import Login from '@/pages/Login'
import Home from '@/pages/Home'

// Jump route
const Redirect: React.FC<{ to: string }> = props => {
  const navigate = useNavigate()
  useEffect(() => {
    navigate(props.to)
  })
  return null
}

const App: React.FC = () => {
  // Default jump/home
  // return (
  //   <div>
  //     <Routes>
  //       <Route path="/" element={<Layout />}>
  //         {/* Method 1: Add the index attribute and remove its own path */}
  //         <Route index element={<Home />} />
  //       </Route>
  //       <Route path="/Login" element={<Login />} />
  //       <Route path="*" element={<NotFound />} />
  //     </Routes>
  //   </div>
  // )

  return (
    <div>
      <Routes>
        {/* Method 2: */}
        <Route path="/" element={<Redirect to="/home" />} />
        <Route path="/" element={<Layout />}>
          <Route path="/home" element={<Home />} />
        </Route>
        <Route path="/Login" element={<Login />} />
        <Route path="*" element={<NotFound />} />
      </Routes>
    </div>
  )
}

export default App

In this way,<Outlet/>will render the About component by default when accessing/

  1. Routing wildcard
  • The whole react router supports the following wildcards
/groups
/groups/admin
/users/:id
/users/:id/messages
/files/*
/files/:id/*
123456

Note that the following regular methods are not supported in V6

/users/:id?
/tweets/:id(\d+)
/files/*/cat.jpg
/files-*
1234

The * here can only be used after/, not in the middle of the actual path

For NotFound routing, * can be used instead

function App() {
 return (
   <Routes>
     <Route path="/" element={<Home />} />      
     <Route path="dashboard" element={<Dashboard />} />      
     <Route path="*" element={<NotFound />} />    
   </Routes>
 );
}
123456789
  1. Get the parameters useParams and useSearchParams

Assume existing App route

function App() {
    return (
      <Routes>
        <Route path="user" element={<Users />}>       
  	      <Route path=":id" element={<UserDetail />} />       
  	      <Route path="create" element={<NewUser />} />     
        </Route>
      </Routes>
    );
}
12345678910

In UserDetail, you need to use useParams to obtain the corresponding parameters

import { useParams } from "react-router-dom";

export default function UserDetail() {
 let params = useParams();
 return <h2>User: {params.id}</h2>;
}
123456

useSearchParams is relatively complex. It returns a current value and a set method

let [searchParams, setSearchParams] = useSearchParams();

You can use searchParams Get ("id") to get the parameters. At the same time, the page can also set SearchParams ({"id": 2}) to change the route, so that when accessing http://URL/user?id=111 You can get and set the path when

  1. useNavigate

useNavigate is a new hook that replaces useHistory in the original V5. Its usage is similar to useHistory, and it is lighter in overall use. Its declaration method is as follows:

declare function useNavigate(): NavigateFunction;

interface NavigateFunction {
 (
   to: To,
   options?: { replace?: boolean; state?: State }
 ): void;
 (delta: number): void;
}
123456789
 //js writing method
 let navigate = useNavigate();
 function handleClick() {
   navigate("/home");
 }
 //Component writing
 function App() {
    return <Navigate to="/home" replace state={state} />;
 }
 //Replace the original go goBack and goForward
<button onClick={() => navigate(-2)}>
   Go 2 pages back
 </button>
 <button onClick={() => navigate(-1)}>Go back</button>
 <button onClick={() => navigate(1)}>    Go forward  </button>
 <button onClick={() => navigate(2)}>    Go 2 pages forward  </button>
12345678910111213141516

2, Difference from V5

1. Replace<Switch>with<Routes>children

V5 writing method:

 function App() {
   return (
     <Switch>
       <Route exact path="/">
         <Home />
       </Route>
       <Route path="/about">
         <About />
       </Route>
       <Route path="/users/:id" children={<User />} />     
     </Switch>
   );
 }

V6 writing method

 function App() {
   return (
     <Routes>
       <Route index path="/" element={<Home />} />      
	       <Route path="about" element={<About />} />       
	       <Route path="/users/:id" element={<User />} />     
       </Routes>
   );
 }

2. Remove<Redirect>from the Switch and replace it with Redirect in the react router dom, or use<Navigate>to implement

V5 writing method:

 <Switch>
   <Redirect from="about" to="about-us" />
 </Switch>

V6 writing method:

 <Route path="about" render={() => <Redirect to="about-us" />}

3.<Link to>Support relative position

The to attribute in V5 only supports absolute positions. For example,<Lint to="me">means<Lint to="/me">. If you are in the Users component at that time, you need to<Lint to="/users/me">to jump. In V6, the Link supports relative location by default, that is,<Lint to="me">is equivalent to<Lint to="/users/me">in the Users component, and supports relative path writing methods such as'... 'and'. '.

// If your routes look like this
<Route path="app">
<Route path="dashboard">
 <Route path="stats" />
</Route>
</Route>

// and the current URL is /app/dashboard (with or without
// a trailing slash)
<Link to="stats">               => <a href="/app/dashboard/stats">
<Link to="../stats">            => <a href="/app/stats">
<Link to="../../stats">         => <a href="/stats">
<Link to="../../../stats">      => <a href="/stats">

4. Use useNavigate instead of useHistory

You can refer to the use of useNavigate above, which will not be repeated here

3, Route configuration, nested routes

React Router provides two interfaces to configure routes

  • : By means of components in jsx

  • useRouters is configured by object

Example: In index.js, configure

import React from 'react';
import ReactDOM from 'react-dom';
import { store } from './app/store';
import { Provider } from 'react-redux';
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import App from './App';
import { PostsList  } from './features/posts/PostsList';
import { SinglePostPage } from './features/posts/SinglePostPage';
import * as serviceWorker from './serviceWorker';
import './index.css';
 
ReactDOM.render(
  <React.StrictMode>
    <Provider store={store}>
      <BrowserRouter>
        <Routes>
          <Route path='/' element={<App />} />
           {/* Nested Route  */}
          <Route path="/postList" element={<PostsList />}>
            <Route index element={<div>I am index Default Subroute</div>} />
            <Route path=":id" element={<div>I am a sub routing element</div>} />
          </Route>
          <Route path="/singlePostPage/:postId" element={<SinglePostPage />} />
          <Route path="*" element={<App />} />
        </Routes>
      </BrowserRouter>
    </Provider>
  </React.StrictMode>,
  document.getElementById('root')
);
serviceWorker.unregister();

For example: configure through useRouters in index.js, and the configuration here can be proposed to a separate file

import React from 'react';
import ReactDOM from 'react-dom';
import { store } from './app/store';
import { Provider } from 'react-redux';
import { BrowserRouter, useRoutes } from 'react-router-dom';
import App from './App';
import { PostsList  } from './features/posts/PostsList';
import { SinglePostPage } from './features/posts/SinglePostPage';
import './index.css';
 
const GetRoutes = () => {
  const routes = useRoutes([
    { path: '/', element: <App /> },
    { 
      path: '/postList',
      element: <PostsList />,
      children: [
        { path: '/postList/:id', element: <div>I am a sub routing element</div> },
        { path: '*', element: <div>404</div>}
      ],
    },
    { path: '/singlePostPage/:postId', element: <SinglePostPage /> },
    { path: '*', element: <div>404</div>}
  ])
  return routes;
}
ReactDOM.render(
  <React.StrictMode>
    <Provider store={store}>
      <BrowserRouter>
        <GetRoutes />
      </BrowserRouter>
    </Provider>
  </React.StrictMode>,
  document.getElementById('root')
);

be careful nesting Routes need to render their child route elements in the parent route using the portlet

import React from 'react';
import { useSelector } from 'react-redux';
import { Link, Outlet } from 'react-router-dom'
 
export const PostsList = () => {
  const posts = useSelector(state => state.posts);
  const renderedPosts = posts.map(post => (
    <div key={post.id}>
      <h3>{post.title}</h3>
      <p>{post.content.substring(0,100)}</p>
      <Link to={`/singlePostPage/${post.id}`}> View details</Link>
    </div>
  ))
  return (
    <section>
      <h2>posts</h2>
      {renderedPosts}
      {/* Subroute render location */}
      <Outlet />
    </section>
  )
}

4, Summary

The V6 version of the react router upgrades the original nested route writing method, and re implements useNavigate to replace useHistory, which is better understood on the whole. Of course, there are still some other properties and methods that have not been introduced. If you have other things you want to know, you can also reply to me to add.

Reference link:

Details of the use of React Router V6 Link to the original text: https://blog.csdn.net/weixin_44733660/article/details/123204029

React Router v6 route configuration, nested route original link: https://blog.csdn.net/Snow_GX/article/details/123656412

Tags: Front-end Javascript React

Posted by rossh on Mon, 26 Sep 2022 01:51:43 +0930