6
头图

join us!

Mountain" , providing front-end developers with technical information and a series of basic articles. For a better user experience, please move to our official website rookies (160f12776f075a https://xhs-rookies.com/ ) to learn and get the latest articles in time.

"Code tailor" , if you are interested in our article or want to make some suggestions, follow "Novices of Xiaohe Mountain" public account, contact us, you can also watch it on WeChat Our article. Every suggestion or approval is a great encouragement to us

Preface

In this section we will introduce React in react - router , the configuration and use of route jump

This article will introduce you to the following:

  • react-router know 060f12776f07f5
  • react-router basic use
  • react-router advanced use
  • react-router-config

Get to know react-router

If this is your first contact with the term router, you can go to here add your knowledge of routing and then read on.

Note: following content is based on the react-router v5 version, if it does not match the reader's current use, please use the official website as the main

Install react-router :

yarn add react-router-dom

npm install react-router-dom

What is react-router ?

React Router is a set of navigation components that are combined with your application in a declarative manner. Whether you want to provide bookmarkable URLs for your web applications or use composable navigation methods in React Native, React Router can be used anywhere React renders

react-router is a set of navigation components that are combined with your application in a declarative manner. In other words, react-router is React system. It manages URLs to achieve component switching and status changes

Basic use of react-router

React Router are mainly divided into three categories:

Router BrowserRouter and HashRouter

  • BrowserRouter uses a regular URL path to create a example.com/some/path , but they require the correct configuration of the server
  • HashRouter the current position is stored in URL hash portion, thus URL looks similar http://example.com/#/your/page , since the hash is never sent to the server, which means that no special server configuration

The main difference between the two is the way they store URL and communicate with the Web

Route matchers, such as Switch and Route:

When rendering the Switch component, it will search its Route sub-elements to find elements URL , and it will present the first Route and ignore all other routes. This means you should put Route that contains more specific paths before less specific routes

Switch

Let's look at the following routing rules:

  • When we match a certain path, we will find that there are some problems;
  • For example, when the /about path is matched, /:userid is also matched, and the last NoMatch component is always matched;
<Route exact path="/" component={Home} />
<Route path="/about" component={About} />
<Route path="/profile" component={Profile} />
<Route path="/:userid" component={User}/>
<Route component={NoMatch}/>

what is the reason? By default, react-router as long as the path is matched to the Route corresponding components will be rendered;

But in actual development, we often hope to have an exclusive thought:

  • As long as the first one is matched, the subsequent ones should not continue to match;
  • At this time, we can use Switch to wrap Route
<Switch>
  <Route exact path="/" component={Home} />
  <Route path="/about" component={About} />
  <Route path="/profile" component={Profile} />
  <Route path="/:userid" component={User} />
  <Route component={NoMatch} />
</Switch>

Route

Its most basic responsibility is to present some UI when its path matches the current URL

There are three types of Route rendering methods

  • <Route component>
  • <Route render>
  • <Route children>

Route component

Render route props only when the position matches

import React from "react";
import ReactDOM from "react-dom";
import { BrowserRouter as Router, Route } from "react-router-dom";

// All route props (match, location and history) are available to User
function User(props) {
  return <h1>Hello {props.match.params.username}!</h1>;
}

ReactDOM.render(
  <Router>
    <Route path="/user/:username" component={User} />
  </Router>,
  node
);

When you use this method to load, router usually based on a given component to call React.createElement create a new React elements. This means that if you are rendering a component with an inline function here, it will create a new function every time it is rendered, that is, uninstall the component and install the new component instead of updating it. So when you use the inline function to render the component, please choose the render or children method

Route render

You can pass in a function that is called when the position is matched, instead of using the component prop to create a new React element for you

import React from "react";
import ReactDOM from "react-dom";
import { BrowserRouter as Router, Route } from "react-router-dom";

// convenient inline rendering
ReactDOM.render(
  <Router>
    <Route path="/home" render={() => <div>Home</div>} />
  </Router>,
  node
);

// wrapping/composing
// You can spread routeProps to make them available to your rendered Component
function FadingRoute({ component: Component, ...rest }) {
  return (
    <Route
      {...rest}
      render={routeProps => (
        <FadeIn>
          <Component {...routeProps} />
        </FadeIn>
      )}
    />
  );
}

ReactDOM.render(
  <Router>
    <FadingRoute path="/cool" component={Something} />
  </Router>,
  node
);

It should be noted that the priority of <Route component> is higher than <Route render>, so do not call both methods Route

Route children

The working principle is the same as <Route render>, except that it will be called regardless of whether it matches or not

import React from "react";
import ReactDOM from "react-dom";
import {
  BrowserRouter as Router,
  Link,
  Route
} from "react-router-dom";

function ListItemLink({ to, ...rest }) {
  return (
    <Route
      path={to}
      children={({ match }) => (
        <li className={match ? "active" : ""}>
          <Link to={to} {...rest} />
        </li>
      )}
    />
  );
}

ReactDOM.render(
  <Router>
    <ul>
      <ListItemLink to="/somewhere" />
      <ListItemLink to="/somewhere-else" />
    </ul>
  </Router>,
  node
);

It should be noted that the priority of <React children> is higher than the above two priorities

And these three rendering methods will pass the same route props

  • match: Contains information about how <Route path> matches URL
  • location: represents the current location of the application
  • history: Used to manage session history in various ways in JavaScript

Route navigation, for example: Link, NavLink, Redirect

  • <Link> component will create a link in your application. Wherever presented <Link> , the anchor will be presented in HTML document, and it will eventually be rendered a elements
  • NavLink adds some style attributes on the basis of Link prop matches the current position, you can set a activeClassName (selected) style for it.
  • Any time to enforce navigation, you can use <Redirect> , when presented <Redirect> when, according to prop of to navigate values.
NavLink

path is selected, the corresponding a element becomes red

  • activeStyle : the style when active (when matching);
  • activeClassName : class added when active;
  • exact : Whether it matches exactly;
<NavLink to="/" activeStyle={{color: "red"}}>home</NavLink>
<NavLink to="/about" activeStyle={{color: "red"}}>about</NavLink>
<NavLink to="/profile" activeStyle={{color: "red"}}>profile</NavLink>

However, we will find that when about or profile is selected, the first one will also turn red:

  • The reason is that /path also matches /about or /profile
  • This time, we can first NavLink added in the exact property
<NavLink exact to="/" activeStyle={{ color: 'red' }}>
  home
</NavLink>

The default activeClassName :

  • In fact, when the default match is successful, NavLink will add a dynamic active class ;
  • So we can also write the style directly
a.active {
  color: red;
}

Of course, if you are worried that this class is used in other places, there will be a cascade of styles, you can also customize class

<NavLink exact to="/" activeClassName="link-active">home</NavLink>
<NavLink to="/about" activeClassName="link-active">about</NavLink>
<NavLink to="/profile" activeClassName="link-active">profile</NavLink>
Redirect

Redirect used for routing redirection. When this component appears, it will jump to the corresponding to path, and the most common scenario for Redirect

  • User browser input User interface url ;
  • If the user is not logged in, it needs to be redirected to the login page. If you have logged in, you can enter the User interface

Define the Login corresponding to the Route App.js in advance:

<Switch>
  ...其他Route
  <Route path="/login" component={Login} />
  <Route component={NoMatch} />
</Switch>

Write the corresponding logic code in User.js

import React, { PureComponent } from 'react'
import { Redirect } from 'react-router-dom'

export default class User extends PureComponent {
  constructor(props) {
    super(props)

    this.state = {
      isLogin: false,
    }
  }

  render() {
    return this.state.isLogin ? (
      <div>
        <h2>微信公众号:小和山的菜鸟们</h2>
        <h2>用户名: Coder tailor</h2>
      </div>
    ) : (
      <Redirect to="/login" />
    )
  }
}

Advanced use of react-router

Nested routing

This example shows how nested routing works. The route /topics loads the Topics component, which conditionally presents any further <Route> based on the path :id value.

import React from "react";
import {
  BrowserRouter as Router,
  Switch,
  Route,
  Link,
  useRouteMatch,
  useParams
} from "react-router-dom";

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

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

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

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

function Topics() {
  let match = useRouteMatch();

  return (
    <div>
      <h2>Topics</h2>

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

      {/* Topics 页面有自己的 <Switch>,其中包含更多基于 /topics URL 路径
          的路由。您可以将此处的第二个 <Route> 视为所有主题的“索引”页面,或者
          未选择主题时显示的页面 */}
      
      <Switch>
        <Route path={`${match.path}/:topicId`}>
          <Topic />
        </Route>
        <Route path={match.path}>
          <h3>Please select a topic.</h3>
        </Route>
      </Switch>
    </div>
  );
}

function Topic() {
  let { topicId } = useParams();
  return <h3>Requested topic ID: {topicId}</h3>;
}

Dynamic routing

When we discuss dynamic routing, we are referring to the routing that occurs when your application is rendered, rather than being configured or agreed upon outside of the running application.

This means that almost everything is a component in React Router The following is API to understand its working principle:

Router component for the environment you want to locate and present it on the top of the application.

// react-dom (what we'll use here)
import { BrowserRouter } from "react-router-dom";

ReactDOM.render(
  <BrowserRouter>
    <App />
  </BrowserRouter>,
  el
);

const App = () => (
  <div>
    <nav>
      <Link to="/dashboard">Dashboard</Link>
    </nav>
    <div>
      <Route path="/dashboard" component={Dashboard} />
    </div>
  </div>
);

The Route will present <Dashboard {... props} /> , where props is router-specific, such as { match, location, history } . If the user is not on / dashboard , Route will appear as null .

react-router-config

There are many ways to configure routing, let’s take a look at the best practices from the official website

// 路由配置只是数据
// React 非常擅长将数据映射到组件中,而 <Route> 是一个组件.

//我们的路由配置只是一个带有 path 和 component props 的逻辑"路由"数组
//排序方式与你在 `<Switch>` 中的顺序相同。

//路由配置
const routes = [
  {
    path: "/sandwiches",
    component: Sandwiches
  },
  {
    path: "/tacos",
    component: Tacos,
    routes: [
      {
        path: "/tacos/bus",
        component: Bus
      },
      {
        path: "/tacos/cart",
        component: Cart
      }
    ]
  }
];

Embed in App

export default function App() {
  ReactDOM.render(
    <Router>
      <div>
        <ul>
          <li>
            <Link to="/tacos">Tacos</Link>
          </li>
          <li>
            <Link to="/sandwiches">Sandwiches</Link>
          </li>
        </ul>

        <Switch>
          {routes.map((route, i) => (
            <RouteWithSubRoutes key={i} {...route} />
          ))}
        </Switch>
      </div>
    </Router>
  ,document.getElementById('root')
  )
}

Components are here

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

function Tacos({ routes }) {
  return (
    <div>
      <h2>Tacos</h2>
      <ul>
        <li>
          <Link to="/tacos/bus">Bus</Link>
        </li>
        <li>
          <Link to="/tacos/cart">Cart</Link>
        </li>
      </ul>

      <Switch>
        {routes.map((route, i) => (
          <RouteWithSubRoutes key={i} {...route} />
        ))}
      </Switch>
    </div>
  );
}

function Bus() {
  return <h3>Bus</h3>;
}

function Cart() {
  return <h3>Cart</h3>;
}

//<Route> 的特殊包装器,它知道如何通过将"子"路由
//传递到它呈现的组件的 `routes` 属性来处理它们。
function RouteWithSubRoutes(route) {
  return (
    <Route
      path={route.path}
      render={props => (
        // pass the sub-routes down to keep nesting
        <route.component {...props} routes={route.routes} />
      )}
    />
  );
}

Preview of the next section

In this section, we have learned about the React-Router and the supplementary content of the components. At this point, we have completed the knowledge of React. In the next section, we will add the login function to the previous message board!


小和山的菜鸟们
377 声望2.1k 粉丝

每日进步的菜鸟,分享前端学习手册,和有心学习前端技术的小伙伴们互相探讨,一同成长。