Skip to content

受保护路由 ​

本节目标:理解“受保护路由”的核心思路,并能把它用于实际开发或面试表达。

有权限才可以访问:
src\index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { HashRouter as Router, Route, Switch, Redirect, Link } from './react-router-dom'; import Home from './components/Home';
import User from './components/User';
import Profile from './components/Profile';
import Protected from './components/Protected'; import Login from './components/Login'; ReactDOM.render(
  <Router>
    <ul>
      <li><Link to="/">首页</Link></li>
      <li><Link to="/user" >用户管理</Link></li>
      <li><Link to="/profile" >个人中心</Link></li>
    </ul>
    <Switch>
      <Route path="/" component={Home} exact />
      <Route path="/user" component={User} />
      <Protected path="/profile" component={Profile} />
      <Route path="/login" component={Login} /><Redirect to="/" />
    </Switch>
  </Router>
  , document.getElementById('root'));
src\react-router\Route.js
import React from 'react';
import RouterContext from './RouterContext';
import matchPath from './matchPath';
class Route extends React.Component {
  static contextType = RouterContext;
  render() {
    const { history, location } = this.context;
    const { component: RouteComponent, computedMatch, render, children } = this.props;
    const match = computedMatch ? computedMatch : matchPath(location.pathname, this.props);
    const routeProps = { history, location };
    let renderElement = null;// null也一个合法的react渲染节点 代表我们render的返顺值,代表此组件将要渲染的内容
    if (match) {
      routeProps.match = match;
      //RouteComponent>render>children
      if (RouteComponent) {//如果传递了 component属性,优先渲染component
        renderElement = <RouteComponent {...routeProps} />
      } else if (render) {
        renderElement = render(routeProps);
      } else if (children) {
        renderElement = children(routeProps);
      } else {
        renderElement = null;
      }
    } else {//TODO
      if (children) {
        renderElement = children(routeProps);
      } else {
        renderElement = null;
      }
    }
    return renderElement
  }
}
export default Route;
/**
 * 指定一个route组件如何渲染有三种方式
 * 1.component 如果你渲染的是一个固定 的组件,确定的组件的话就可以component
 * 2.render 如果你想自己确认,自定义渲染逻辑就可以用render
 *
 * 1和2都是要求路径匹配才渲染或执行,如果路径不匹配什么不渲染
 * 3.children
 * 不管路由是否匹配,都渲染
 */
src\components\Login.js
import React, { Component } from 'react'
export default class Login extends Component {
  login = () => {
    localStorage.setItem('login', 'true');
    let to = '/';
    if (this.props.location.state) {
      to = this.props.location.state.to || '/';
    }
    this.props.history.push(to);
  }
  render() {
    return (
      <button onClick={this.login}>登录</button>
    )
  }
}
src\components\Protected.js
import React from 'react'
import { Redirect, Route } from '../react-router-dom';
const Protected = (props) => {
  const { path, component: RouteComponent } = props;
  return (
    <Route
      path={path}
      render={
        (routeProps) => (
          localStorage.getItem('login')
            ? <RouteComponent {...routeProps} />
            : <Redirect to={{
              pathname: '/login',
              state: { from: path }
            }} />
        )
      }
    />
  )
}
export default Protected;

本站总访问 — 次