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.
- Create demo create react app my first react
Install the react router component
- 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
- 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 Name | effect | explain |
---|---|---|
<Routers> | A set of routes | Instead of the original<Switch>, all sub routes are represented by the basic Router children |
<Router> | Basic route | Router 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 components | Jump to use in the actual page |
<Outlet/> | Adaptive Rendering Components | Automatically select components according to the actual routing url |
hooks Name | effect | explain |
---|---|---|
useParams | Return the current parameter | Read parameters according to path |
useNavigate | Return to the current route | Replace useHistory in the original V5 |
useOutlet | Return the element generated according to the route | |
useLocation | Returns the current location object | |
useRoutes | Like Routers component, it is only used in js | |
useSearchParams | Used 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.
- 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> ); }
- 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/
- 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
- 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
- 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