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 060f12776f07f5react-router
basic usereact-router
advanced usereact-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 aexample.com/some/path
, but they require the correct configuration of the serverHashRouter
the current position is stored inURL
hash portion, thusURL
looks similarhttp://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 lastNoMatch
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 wrapRoute
<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 inHTML
document, and it will eventually be rendereda
elementsNavLink
adds some style attributes on the basis ofLink
prop
matches the current position, you can set aactiveClassName
(selected) style for it.- Any time to enforce navigation, you can use
<Redirect>
, when presented<Redirect>
when, according toprop
ofto
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 theexact
property
<NavLink exact to="/" activeStyle={{ color: 'red' }}>
home
</NavLink>
The default activeClassName
:
- In fact, when the default match is successful,
NavLink
will add a dynamicactive 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
interfaceurl
; - 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!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。