Use of react router DOM in hook comparison between v6 and v5

preface

React router DOM is a common routing component in react. With the update of the new version, especially in order to cooperate with the v6 version of react hook, there have been great changes in the use. This paper aims to compare the old version (v5) and introduce the use of the new version

Introduction to the version of react router DOM

v5 document: https://v5.reactrouter.com/web/guides/quick-start

This article uses two versions: v5(5.3.0) and v6(6.1.1)
Of which:
v5 version is compatible with both class component (before react v16.8) and function component(v16.8 and later, i.e. hook)
v6 version, if you still use this props. history. Push(), props will prompt null value at this time. The three attributes accepted by the routing component by default are removed in the v6 document. The solution given in the official website document is to use the hook of useNavigate(), but the hook can only exist in the function component and cannot be used in the class component

Therefore, if class comment is still used for project development, it is recommended to use V5 and previous versions of react router DOM (the latest version of V5 is v5.3.0)
If you use function component for project development, it is recommended to use the latest v6 Version (although v5 version is compatible with hook usage, it is still a little different from v6)

Main changes:

  1. Discard the # Switch # component and replace it with # Routes # (using intelligent matching path algorithm)
  2. Discard the "Redirect" component and replace it with "Navigate"
  3. Discard the 'useHistory' method and replace it with 'useNavigate'
  4. The Route element component removes the original "component" and "render" attributes and passes them uniformly through the "element" attribute: < Route element = {< home / >} >
  5. Route} component supports nested writing (v3 version usage regression)
  6. The {path} rule of the Route} component is changed, and the class regular writing method is no longer supported
  7. It eliminates the problem of fuzzy jump of Link # component when the path with backslash in # v5 # version
  8. The Link component supports the automatic carrying of the current parent route and the relative path writing method/ home
  9. The # useRoutes # method is added to replace the previous write method of react route config, and nesting is also supported
  10. Other API name changes

1. Installation dependency

npm i react-router-dom

2. Introduce the components required for routing and page components

import { BrowserRouter, Routes, Route } from 'react-router-dom';
import Foo from './Foo';
import Bar from './Bar';
​
function App(){
    return (
        <BrowserRouter>
            <Routes>
                <Route path='/foo' element={Foo} />
                <Route path='/bar' element={Bar} />
            </Routes>
        </BrowserRouter>
    )
}

Note: the BrowserRouter component should be placed outside all the top-level components, so as to ensure that there is no error when the internal components use Link for route jump

1, Switch renamed Routes

// v5
<Switch>
    <Route exact path="/"><Home /></Route>
    <Route path="/profile"><Profile /></Route>
</Switch>

// v6
<Routes>
    <Route path="/" element={<Home />} />
    <Route path="profile/*" element={<Profile />} />
</Routes>

2, New features and changes of Route

component/render is replaced by element

In short. It's just getting better.

import Profile from './Profile';

// v5
<Route path=":userId" component={Profile} />
<Route
  path=":userId"
  render={routeProps => (
    <Profile routeProps={routeProps} animate={true} />
  )}
/>

// v6
<Route path=":userId" element={<Profile />} />
<Route path=":userId" element={<Profile animate={true} />} />

3, Route jump

When jumping a route, if the path starts with / it is an absolute route, otherwise it is a relative route, that is, it is changed relative to the "current URL"

3, Link assembly

The Link component can only be used inside the Router, so the components using the Link component must be placed in the Router on the top floor

import { Link } from 'react-router-dom';
​
<Link to='foo'>to foo</Link>

4, NavLink assembly

The functions of NavLink component and Link component are the same. The difference is that you can judge whether its to attribute is the currently matched route
The style or className of the NavLink component can receive a function, which receives an isActive parameter, and the style can be adjusted according to the parameter

import { NavLink } from 'react-router-dom';
​
function Foo(){
    return (
        <NavLink
            style={ (isActive) => ({color: isActive ? 'red' : '#fff'}) }
        >Click here</NavLink>
    )
}

5, Outlet (render any matching child routing pages)

      return (
        <div className="A">
          <h3>I am A assembly --------- Example of programming route navigation</h3>
          <div className="A-navBox">
            <Button type="primary" onClick={() => navigateRouter(1, 1, "i am Jason Ma")}>
              params Chuan Shen
            </Button>
            <Button onClick={() => navigateRouter(2, 18, "i am Jason Ma")}>search Chuan Shen</Button>
            <Button type="dashed" onClick={() => navigateRouter(3, 999, "i am Jason Ma")}>
              state Chuan Shen
            </Button>
          </div>

          {/* Render any matching child routing pages */}
          <Outlet></Outlet>
        </div>
  );

6, Get params parameter

Define the path parameter in the path attribute in the Route component
Access path parameters through useParams hook within the component

<BrowserRouter>
    <Routes>
        <Route path='/foo/:id' element={Foo} />
    </Routes>
</BrowserRouter>
​
import { useParams } from 'react-router-dom';
export default function Foo(){
    const params = useParams();
    return (
        <div>
            <h1>{params.id}</h1>
        </div>
    )
}

In previous versions, the props of the component will contain a match object, in which the path parameters can be obtained. But in the latest 6 In version x, parameters cannot be obtained from props.

Moreover, the withRouter high-order components for class components have been removed. Therefore, for class components, there are two compatible methods of using parameters:

Rewrite a class component to a function component
Byte write a HOC to wrap the class component, get the parameters with useParams, and pass them into the original class component through props

7, Programmed route navigation uses useNavigate instead of useHistory

Using useNavigate hook function to generate navigate object, you can complete route jump through JS code

// v5
import { useHistory } from 'react-router-dom';
 
 
function MyButton() {
  let history = useHistory();
  function handleClick() {
    history.push('/home');
  };
  return <button onClick={handleClick}>Submit</button>;
};

Now, history Replace push() with navigation():

// v6
import { useNavigate } from 'react-router-dom';
 
 
function MyButton() {
  let navigate = useNavigate();
  function handleClick() {
    navigate('/home');
  };
  return <button onClick={handleClick}>Submit</button>;
};

The usage of history will also be replaced by:

// v5
history.push('/home');
history.replace('/home');
 
 
// v6
navigate('/home');
navigate('/home', {replace: true});

8, search parameter

Query parameters do not need to be defined in the route
Use useSearchParams hook to access query parameters. Its usage is similar to useState, which returns the current object and the method to change it
When changing searchParams, all query parameters must be passed in, otherwise the existing parameters will be overwritten

import { useSearchParams } from 'react-router-dom';
​
// Current path is / foo?id=12
function Foo(){
    const [searchParams, setSearchParams] = useSearchParams();
    console.log(searchParams.get('id')) // 12
    setSearchParams({
        name: 'foo'
    }) // /foo?name=foo
    return (
        <div>foo</div>
    )
}

9, Default route

Definition: in nested routes, if the URL only matches the parent URL, the route with index attribute will be displayed in the Outlet

<Routes>
    <Route path='/foo' element={Foo}>
        <Route index element={Default}></Route>
        <Route path='bar' element={Bar}></Route>
    </Route>
</Routes>

When the url is / Foo: the Outlet in Foo will display the Default component
When the url is / foo/bar: the Outlet in Foo will be displayed as a Bar component

10, Fully matched routing

Definition: when the value of path attribute is *, any (non empty) path can be matched, and the matching has the lowest priority. Can be used to set 404 pages.

<Routes>
    <Route path='/foo' element={Foo}>
        <Route path='bar' element={Bar}></Route>
        <Route path='*' element={NotFound}></Route>
    </Route>
</Routes>

11, Multi group routing

Usually, there is only one Routes component in an application.

However, multiple route exits can also be defined according to actual needs (for example, the sidebar and main page change with the URL)

<Router>
    <SideBar>
        <Routes>
            <Route></Route>
        </Routes>
    </SideBar>
    <Main>
        <Routes>
            <Route></Route>
        </Routes>
    </Main>
</Router>

12, Redirect

When you want to redirect to path / b under a path / A, you can redirect to other paths through the navigation component

It is equivalent to the Redirect component in the previous version

import { Navigate } from 'react-router-dom';
function A(){
    return (
        <Navigate to="/b" />
    )
}

React router DOM programmed route navigation (v5)

1.push jump + params parameter
 props.history.push(`/b/child1/${id}/${title}`);
Copy code
2.push jump + carry search parameter
props.history.push(`/b/child1?id=${id}&title=${title}`);
Copy code
3.push jump + carry state parameter
props.history.push(`/b/child1`, { id, title });
Copy code
4.replace jump + params parameter carried
this.props.history.replace(`/home/message/detail/${id}/${title}`)
Copy code
5.replace jump + carry search parameter
this.props.history.replace(`/home/message/detail?id=${id}&title=${title}`)
Copy code
6.replace jump + carry state parameter
this.props.history.replace(`/home/message/detail`, { id, title });
Copy code
7. Move forward
this.props.history.goForward();
Copy code
8. Fallback
this.props.history.goForward();
Copy code
9. Forward or backward (go)
this.props.history.go(-2); //Back to the first two routes
 Copy code
Use programmatic routing navigation in general components (non routing components)
import {withRouter} from 'react-router-dom'

class Header extends Component {
    // After withRouter(Header), you can use this in general components props. history 
    //...
}

export default withRouter(Header)

Copy code

React router DOM programmed route navigation (v6)

// Programming navigation in v6 version uses useNavigate (the following is the introduction code)
import {  useNavigate } from "react-router-dom";
export default function A() {
  const navigate = useNavigate();
  //...
}
Copy code
1.push jump + params parameter
 navigate(`/b/child1/${id}/${title}`);
Copy code
2.push jump + carry search parameter
navigate(`/b/child2?id=${id}&title=${title}`);
Copy code
3.push jump + carry state parameter
navigate("/b/child2", { state: { id, title }});
Copy code
4.replace jump + params parameter carried
navigate(`/b/child1/${id}/${title}`,{replace: true});
Copy code
5.replace jump + carry search parameter
navigate(`/b/child2?id=${id}&title=${title}`,{replace: true});
Copy code
6.replace jump + carry state parameter
navigate("/b/child2", { state: { id, title },replace: true});


Posted by HeyRay2 on Tue, 10 May 2022 17:51:56 +0300