React Router (Part 1) : Get started with the React Router. This section introduces how the React Router works, its core API, and some basic examples. This article practices some applications in complex routing scenarios.

Pass parameters through the URL

Passing parameters through the URL is a common requirement, such as displaying the ID of an article/item. It is recommended that parameters be part of the path (rather than query parameters) as this is more search engine friendly and semantic.

How to pass parameters through URL

To demonstrate an example of passing articleId 🌰

function App() {
  return (
    <Router>
      <nav>
        <ul>
          <li>
            <Link to="/article/1">aritcle 1</Link>
          </li>
          <li>
            <Link to="/article/2">aritcle 2</Link>
          </li>
          <li>
            <Link to="/article/3">aritcle 3</Link>
          </li>
        </ul>
      </nav>
      <div class="page-container">
        <Route path="/article/:id" component={Article}></Route>
      </div>
    </Router>
  );
}
Copy the code

How to obtain parameters

The React Router Render component passes a match attribute as a higher-order component, and the parameters passed can be accessed in mate. props.

  • Hook – useParamsReact Router V5.1 Added
import { useParams } from "react-router-dom";

// Note that the component is wrapped in 
      
<Route path="/blog/:slug">
  <BlogPost />
</Route>;

function BlogPost() {
  let { slug } = useParams();
  return <div>Now showing post {slug}</div>;
}
Copy the code
  • Function components pass({ match }) => ()To obtain parameters
function Article({ match }) {
  return <div> {match.params.id} </div>;
}
Copy the code
  • Class component throughthis.props.match
class Article extends React.Component {
  render() {
    const { match } = this.props;
    return <div>{match.params.id}</div>; }}Copy the code

To use match, the component must be written in component (
).

Fuzzy matching of paths

The React Router uses path-to-regexp, a library that converts string paths into regular expressions, to handle urls and parameters.

const { pathToRegexp } = require("path-to-regexp");
Copy the code

? : Matches 0 or 1 times

const regexp = pathToRegexp("/:foo/:bar?");
// keys = [{ name: 'foo', ... }, { name: 'bar', prefix: '/', modifier: '?' }]

regexp.exec("/test");
//=> [ '/test', 'test', undefined, index: 0, input: '/test', groups: undefined ]

regexp.exec("/test/route");
//=> [ '/test/route', 'test', 'route', index: 0, input: '/test/route', groups: undefined ]
Copy the code

* : matches 0 or more times

const regexp = pathToRegexp("/:foo*");
// keys = [{ name: 'foo', prefix: '/', modifier: '*' }]

regexp.exec("/");
//=> [ '/', undefined, index: 0, input: '/', groups: undefined ]

regexp.exec("/bar/baz");
//=> [ '/bar/baz', 'bar/baz', index: 0, input: '/bar/baz', groups: undefined ]
Copy the code

+ : matches one or more times

const regexp = pathToRegexp("/:foo+");
// keys = [{ name: 'foo', prefix: '/', modifier: '+' }]

regexp.exec("/");
//=> null

regexp.exec("/bar/baz");
//=> [ '/bar/baz','bar/baz', index: 0, input: '/bar/baz', groups: undefined ]
Copy the code

Custom matching

Wrap a custom re with parentheses.

const regexpNumbers = pathToRegexp("/icon-:foo(\\d+).png");
// keys = [{ name: 'foo', ... }]

regexpNumbers.exec("/icon-123.png");
//=> ['/icon-123.png', '123']

regexpNumbers.exec("/icon-abc.png");
//=> null

const regexpWord = pathToRegexp("/(user|u)");
// keys = [{ name: 0, ... }]

regexpWord.exec("/u");
//=> ['/u', 'u']

regexpWord.exec("/users");
//=> null
Copy the code

The React Router uses \d+ to match the regular expression \d+.

When to pass parameters using the URL

Page status is defined by URL parameters as far as possible for better scalability.

For example, in the attendance information page of an attendance system, should the month information queried be put into the URL? Considering that you may need to access attendance information for the “specified month,” it is more appropriate to leave the month information in the URL parameter.

Embedded routines by

Nested logic is a concept unique to the front end:

  • Each React component can be a container component
  • The React Router’s declarative syntax makes it easy to define nested routines

Layer 1 routing is written normally

export default function App() {
  return (
    <Router>
      <div>
        <ul>
          <li>
            <NavLink exact to="/">
              Home
            </NavLink>
          </li>
          <li>
            <NavLink to="/about">About</NavLink>
          </li>
          <li>
            <NavLink to="/topics">Topics</NavLink>
          </li>
        </ul>

        <Switch>
          <Route exact path="/">
            <Home />
          </Route>
          <Route path="/about">
            <About />
          </Route>
          <Route path="/topics">
            <Topics />
          </Route>
        </Switch>
      </div>
    </Router>
  );
}

function Home() {
  return <h2>Home</h2>;
}

function About() {
  return <h2>About</h2>;
}
Copy the code

The second road yo or conventional writing

Topic component:

function Topics() {
  return (
    <div>
      <h2>Topics</h2>

      <ul>
        <li>
          <NavLink to="/topics/components">Components</NavLink>
        </li>
        <li>
          <NavLink to="/topics/props-v-state">Props v. State</NavLink>
        </li>
      </ul>
      <Switch>
        <Route path="/topics/:topicId">
          <Topic />
        </Route>
        <Route path="/topics">
          <h3>Please select a topic.</h3>
        </Route>
      </Switch>
    </div>
  );
}
Copy the code

As you can see, the nested layer 2 Route is also a common operation, using the coexistence property of

to match the same path multiple times to render different components.

The layer 1 route matching part can also be done with useRouteMatch:

UseRouteMatch: Tries to match the current URL in the same way. React-router is a new Hook for V5.1.

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

function Topics() {
  let match = useRouteMatch();
  /* { isExact: false, params: {}, path: "/topics", url: "/topics", }; * /
  return (
    <div>
      <h2>Topics</h2>

      <ul>
        <li>
          <NavLink to={` ${match.url} /components`} >Components</NavLink>
        </li>
        <li>
          <NavLink to={` ${match.url} /props-v-state`} >Props v. State</NavLink>
        </li>
      </ul>

      <Switch>
        <Route path={` ${match.path} /:topicId`} >
          <Topic />
        </Route>
        <Route path={match.path}>
          <h3>Please select a topic.</h3>
        </Route>
      </Switch>
    </div>
  );
}
Copy the code

Topic component

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

function Topic() {
  const { topicId } = useParams();
  return <h3>Requested topic ID: {topicId}</h3>;
}
Copy the code