React-router is an important part of the React ecosystem. Nowadays, routes for single-page applications of React are mostly managed by the front end, rather than by the back end. The React-Router library is commonly used to manage routes. This article tries to write about the Use of the React-Router, but the API is too dull, and the official documentation is well documented. I will use a common development scenario to see how the React-Router is used. Our general system will have user access restrictions, some pages may require users to have a certain permission to access. This paper uses React-Router to implement a front-end authentication model.
All the code for this article has been uploaded to GitHub, you can take it down to play:Github.com/dennis-jian…
The sample application
The function to be implemented in this article is a common scenario, that is, to control different user roles to access different pages, there are four pages in total:
/index
: Homepage/login
: the login page/backend
: Background page/admin
: Management page
There are three other roles:
Unlogged user
: Access only the home page of the website/index
And the login page/login
The average user
: You can visit the homepage of the website/index
The login page/login
And background page/backend
The administrator
: You can access the management page/admin
And all the other pages
The introduction of the React – the Router
To implement route authentication, we need to build a simple project with these pages using the React-Router. We created a new project using create-react-app and created a Pages folder with the pages we described earlier:
Let’s first write a simple page, first write a title, such as this:
import React from 'react';
function Admin() {
return (
<h1>Administrator page</h1>
);
}
Copy the code
Several other pages are similar.
The new react-router separates the core logic layer from the display layer. The core logic handles route matching and so on. The react-Router does not only support browsers, but also needs to support React Native. The react-Router does not support browsers, so there are several packages under the react-Router:
React-router: Core logic processing that provides some common base classes
React-router-dom: implements browser-specific route listening and redirecting
React-router-native: implements RN-related route listening and redirecting
In practice, we don’t need to refer to the react-router. Instead, we use the react-router-dom, which references the react-router itself. Let’s introduce react-router-dom in our project.
import React from 'react';
import {
BrowserRouter as Router,
Switch,
Route,
} from "react-router-dom";
import Home from './pages/Home';
import Login from './pages/Login';
import Backend from './pages/Backend';
import Admin from './pages/Admin';
function App() {
return (
<Router>
<Switch>
<Route path="/login" component={Login}/>
<Route path="/backend" component={Backend}/>
<Route path="/admin" component={Admin}/>
<Route path="/" component={Home}/>
</Switch>
</Router>
);
}
export default App;
Copy the code
You can then add links to other pages in the Home page with Link:
import React from 'react';
import { Link } from 'react-router-dom';
function Home() {
return (
<>
<h1>Home page</h1>
<ul>
<li><Link to="/login">The login</Link></li>
<li><Link to="/backend">The background</Link></li>
<li><Link to="/admin">The administrator</Link></li>
</ul>
</>
);
}
export default Home;
Copy the code
So far our application runs like this:
Module partition
Although our jump is implemented, everyone can access any page, our previous requirement is to restrict access to the page according to the login role, before writing the code, let’s think about how to do this. Of course, the most intuitive and simple method is to detect the role of the current user on each page, failing to match the error or jump back to the home page. We only have a few pages now, which is fine, but as our application gets bigger and more pages, checking each page once becomes repetitive, so we need to think about this in a different way.
A closer look shows that we have three roles in total, corresponding to three different permissions. The three permissions are hierarchical. The high-level permissions include the low-level permissions, so our page can also be divided into three types according to these permissions:
Public page
: All people can access, not logged in can also access, including the website home page and login pageAverage page
: A page accessible to common login usersAdministrator page
: A page that only administrators can access
In order to manage these three pages, we can extract them into three files and put them in an independent folder routes. The three files are named publicroutes. js, privateroutes.js and adminroutes.js respectively:
For each route file, we can organize such routes into arrays and export them to external calls, such as publicroutes.js:
import Login from '.. /pages';
import Home from '.. /pages/Home';
const publicRoutes = [
{
path: '/login'.component: Login,
exact: true}, {path: '/'.component: Home,
exact: true,},];export default publicRoutes;
Copy the code
Then the place we use outside is directly changed to:
import publicRoutes from './routes/publicRoutes';
function App() {
return (
<Router>
<Switch>{publicRoutes.map( ({path, component, ... routes}) =><Route key={path} path={path} component={component} {. routes} / >
)}
<Route path="/backend" component={Backend}/>
<Route path="/admin" component={Admin}/>
</Switch>
</Router>
);
}
Copy the code
Instead of having a long list of routes in app.js, we just loop through an array. However, we can’t render the Route component directly for login pages and admin pages. It’s better to encapsulate an advanced component and put authentication into this component so that our normal pages don’t need to worry about authentication when implemented.
Encapsulating advanced components
It is easy to encapsulate the authentication component. In the previous section, we used publicRoutes directly to loop the Route component. Our authentication component only needs to add a logic on this basis: Before rendering the real Route component, check whether the current user has the corresponding permissions. If so, directly render the Route component. If not, return a page, which can be the login page or the background home page, according to your own project requirements. The route configuration files privateroutes.js and adminroutes.js have two more parameters than publicroutes.js:
// privateRoutes.js
import Backend from '.. /pages/Backend';
const privateRoutes = [
{
path: '/backend'.component: Backend,
exact: true.role: 'user'.// Role permissions required by the current route
backUrl: '/login' // Routes that do not meet permission redirect requirements},];export default privateRoutes;
Copy the code
Adminroutes.js is similar:
// adminRoutes.js
import Admin from '.. /pages/Admin';
const adminRoutes = [
{
path: '/admin'.component: Admin,
exact: true.role: 'admin'.// The required permission is admin
backUrl: '/backend' // Jump back to background page},];export default adminRoutes;
Copy the code
Then we can write our advanced component, which we’ll call AuthRoute. Note that the backend API will return the role of the current user when we assume that the user is logged in. A user can have multiple roles, such as [‘user’] for a normal user. The administrator role is [‘user’, ‘admin’]. The specific permission validation logic depends on the project permission design. Here is just an example:
// AuthRoute.js
import React from 'react';
import { Route, Redirect } from 'react-router-dom';
function AuthRoute(props) {
const {
user: {
role: userRole
},
role: routeRole, backUrl, ... otherProps } = props;// If the user has permission, render the corresponding route
if (userRole && userRole.indexOf(routeRole) > -1) {
return <Route {. otherProps} / >
} else {
// If you do not have permission, return the configured default route
return <Redirect to={backUrl} />}}export default AuthRoute;
Copy the code
Then use our AuthRoute render adminRoutes and privateRoutes:
/ /... Omit other code...
{privateRoutes.map(
(route) = > <AuthRoute key={route.path} {. route} / >
)}
{adminRoutes.map(
(route) = > <AuthRoute key={route.path} {. route} / >
)}
Copy the code
Login Setting Permission
The user: {role} variable is used in our AuthRoute, but we haven’t set it yet. In real projects, the back-end API returns the role of the current user at login, and the front end stores this permission information in some state management tool, such as Redux. The user configuration is managed using the state of the root component. The two buttons on the Login page change the corresponding state:
import React from 'react';
import { Link } from 'react-router-dom';
function Login(props) {
const {loginAsUser, loginAsAdmin, history} = props;
const userLoginHandler = () = > {
loginAsUser(); // Call the parent method to set user permissions
history.replace('/backend'); // Go to the background page after login
}
const adminLoginHandler = () = > {
loginAsAdmin(); // Call the parent method to set administrator permissions
history.replace('/admin'); // The administrator page is displayed
}
return (
<>
<h1>The login page</h1>
<button onClick={userLoginHandler}>Common User Login</button>
<br/><br/>
<button onClick={adminLoginHandler}>Administrator Login</button>
<br/><br/>
<Link to="/">Back to the home page</Link>
</>
);
}
export default Login;
Copy the code
At this point, we have completed the simple route authentication. The specific results are as follows:
All the code for this article has been uploaded to GitHub, you can take it down to play:Github.com/dennis-jian…
conclusion
React-Router
Can be used to manage the front-end route jump, yesReact
A very important library in ecology.React-Router
To support both browsers andReact-Native
He divided it into three bagsreact-router
The core package,react-router-dom
Browser package,react-router-native
supportReact-Native
. There is no need to import when usingreact-router
, just import the required platform packages.- For routes that require different permissions, we can separate them into different classes and create a separate file. If there are not many routes, we can export multiple arrays in a file.
- For routes that require authentication, we can use an advanced component to encapsulate the logic of permission verification. Other pages only need to be configured and do not care about authentication at all.
The content of this article is simple, as familiarReact-Router
“Is not bad, but we can not only use it, but also know its principle. We’ll look at that in the next articleReact-Router
The source code contains what mystery, we can point a concern not lost, ha ha ~
The resources
The official document: reactrouter.com/web/guides/…
GitHub source address: github.com/ReactTraini…
At the end of this article, thank you for your precious time to read this article. If this article gives you a little help or inspiration, please do not spare your thumbs up and GitHub stars. Your support is the motivation of the author’s continuous creation.
Welcome to follow my public numberThe big front end of the attackThe first time to obtain high quality original ~
“Front-end Advanced Knowledge” series:Juejin. Cn/post / 684490…
“Front-end advanced knowledge” series article source code GitHub address:Github.com/dennis-jian…