React centralized route management + route authentication

Posted by lentin64 on Sat, 19 Feb 2022 22:05:59 +0100

1. Why use react_router_config

Using routes in React generally uses NavLink and Route in React router DOM, writes Route links using NavLink, and registers routes using Route:

import { NavLink, Route } from 'react-router-dom';
...

{/* Routing link */}
<NavLink to="/home">Home</NavLink>
<NavLink to="/about">About</NavLink>

{/* Register routing */}
<Route path="/home" component={Home} />
<Route path="/about" component={About} />

The registered routing part is written in the corresponding components, but once there are too many routing components and the routing nesting relationship is complex, it will be easy to understand the relationship between routing components.

react_router_config can solve this problem, react_router_config writes all route registrations in the same directory js file, the nested relationship between each route can also be clearly obtained, which is very convenient for complex route management.

2. react_router_config basic usage

Install react first_ router_ Config library.

yarn add react_router_config

Create router under the root directory of the project JS file, in the form of required route array, and exposed to the outside:

import Home from './components/Home';
import User from './components/User';

const routes = [
    {
        path: '/home',
        component: Home,
    },
    {
        path: '/user',
        component: User,
    },
];

export default routes;

Components to enable Routing:

import React, { Component } from 'react';
import { renderRoutes } from 'react-router-config';
import { NavLink } from 'react-router-dom';
import routes from './router.js';

export default class App extends Component {
    render() {
        return (
            <div>
                {/* Routing link */}
                <NavLink to="/home">Home</NavLink>
                <NavLink to="/user">User</NavLink>
            
                {/* Use the renderRoutes method in react router config */}
                {renderRoutes(routes)}
            </div>
        );
    }
}

In this way, the basic functions of routing can be realized.

3. Nested routing

Route components A and B are nested in the User component, and routes C and D are nested in the B component. Modify the router JS file, and the sub route can be defined through children:

import Home from './components/Home';
import User from './components/User';
import A from './components/User/A';
import B from './components/User/B';
import C from './components/User/B/C';
import D from './components/User/B/D';

const routes = [
    {
        path: '/home',
        component: Home,
    },
    {
        path: '/user',
        component: User,
        children: [
            {
                path: '/user/a',
                component: A,
            },
            {
                path: '/user/b',
                component: B,
                children: [
                    {
                        path: '/user/b/c',
                        component: C,
                    },
                    {
                        path: '/user/b/d',
                        component: D,
                    },
                ],
            },
        ],
    },
];

export default routes;

User component:

import React, { Component } from 'react';
import { renderRoutes } from 'react-router-config';
import { NavLink } from 'react-router-dom';

export default class User extends Component {
    componentDidMount() {
        console.log(this.props);
    }
    render() {
        return (
            <div>
                User <hr />
                <NavLink to="/user/a">A</NavLink>
                <NavLink to="/user/b">B</NavLink>
                
                {/* You need to pass nested components with props */}
                {renderRoutes(this.props.route.children)}
            </div>
        );
    }
}

Here is a checkmark for componentDidMount(). Take a look at the content printed after the component is mounted:

You can see through this props. route. Children get the registration information of sub routes, so when using the renderRoutes method, you need to pass this props. route. children.

Component B:

import React, { Component } from 'react';
import { renderRoutes } from 'react-router-config';
import { NavLink } from 'react-router-dom';

export default class B extends Component {
    render() {
        return (
            <div>
                BBB
                <hr />
                <NavLink to="/user/b/c">C</NavLink>
                <NavLink to="/user/b/d">D</NavLink>

                {renderRoutes(this.props.route.children)}
            </div>
        );
    }
}

4. Route authentication

Sometimes a component does not want all users to have direct access, but only the logged in users can access it. At this time, routing authentication is required. Return the specified routing component by judging the conditions.

Modify react_ router_ The source code of renderRoutes() function in config, or you can directly define a renderRoutes():

import React from 'react';
import { Route, Redirect, Switch } from 'react-router-dom';

const renderRoutes = (routes, authed, authPath = '/login', extraProps = {}, switchProps = {}) =>
    routes ? (
        <Switch {...switchProps}>
            {routes.map((route, i) => (
                <Route
                    key={route.key || i}
                    path={route.path}
                    exact={route.exact}
                    strict={route.strict}
                    render={props => {
                        if (!route.requiresAuth || authed || route.path === authPath) {
                            return <route.component {...props} {...extraProps} route={route} />;
                        }
                        return (
                            <Redirect
                                to={{ pathname: authPath, state: { from: props.location } }}
                            />
                        );
                    }}
                />
            ))}
        </Switch>
    ) : null;

export default renderRoutes;

If the User component does not want to be accessed by users who are not logged in, modify the User component:

import React, { Component } from 'react';
// import { renderRoutes } from 'react-router-config';
// Introduce your own renderRoutes
import renderRoutes from './utils/renderRoutes';
import { NavLink } from 'react-router-dom';
import routes from './router.js';

const authed = false; // false indicates that you are not logged in
const authPath = '/home'; // Path to jump to

export default class App extends Component {
    render() {
        return (
            <div>
                {/* Routing link */}
                <NavLink to="/home">Home</NavLink>
                <NavLink to="/user">User</NavLink>

                {/* {renderRoutes(routes)} */}
                {renderRoutes(routes, authed, authPath)}
            </div>
        );
    }
}

In this way, when the user is not logged in, if he accesses / user, he will automatically jump back to / home.

Welcome to my blog:
https://lzxjack.top/

Topics: Front-end React