美文网首页
react路由拦截

react路由拦截

作者: 未来在奋斗 | 来源:发表于2019-12-23 15:16 被阅读0次
// 登录拦截,没有路由守卫这个东西,需要拦截的话,可以自己去封装 Route

import React from "react";
import ReactDOM from 'react-dom'
import {
  HashRouter as Router,
  Route,
  Link,
  Redirect,
  withRouter
} from "react-router-dom";

////////////////////////////////////////////////////////////
// 1. Click the public page
// 2. Click the protected page
// 3. Log in
// 4. Click the back button, note the URL each time

const AuthExample = () => (
  <Router>
    <div>
      <AuthButton />
      <ul>
        <li>
          <Link to="/public">公共页面</Link>
        </li>
        <li>
          <Link to="/protected">需要登录验证的页面</Link>
        </li>
        {/* <li>
          <Link to={{ pathname: '/login', state: { from: { pathname: '/abc' } } }}>登录页面</Link>
        </li> */}
      </ul>

      <Route path="/public" component={Public} />
      <Route path="/login" component={Login} />
      {/* PrivateRoute 自定义 的路由组件实现路由拦截功能  通过将props,path="/protected" component={Protected}传过去*/}
      <PrivateRoute path="/protected" component={Protected} />

    </div>
  </Router>
);

const fakeAuth = {
    // fakeAuth登录的对象集合
  isAuthenticated: false, // 登录状态

  // 登录方法
  authenticate(cb) {
    this.isAuthenticated = true;
    setTimeout(cb, 100); // fake async
  },

  // 退出登录方法
  signout(cb) {
    this.isAuthenticated = false;
    setTimeout(cb, 100);
  }
};
// withRouter 方法重新包装router
const AuthButton = withRouter(
  ({ history }) =>
  // 登录状态 登录了就显示退出, 没有登录就显示没有登录
    fakeAuth.isAuthenticated ? (
      <p>
        Welcome!{" "}
        <button
          onClick={() => {
              //  函数式路由跳转
            fakeAuth.signout(() => history.push("/"));
          }}
        >
          退出登录
        </button>
      </p>
    ) : (
      <p>You are not logged in.</p>
    )
);

// 自己对 Route 组件做的一个封装。(高阶组件)
// props.path
// props.component

// rest = { path: '/protected' }
// 自己定义的一个Router组件,来实现路由拦截功能
// component: Component,将props中的component解构赋值出来并且实施重命名,应为下面是要作为组件使用
// ...rest 是接受剩下的元素
const PrivateRoute = ({ component: Component, ...rest }) => (
  <Route
  // 这是在路由中将剩余的props元素展开
    {...rest} // 里面有路径 和路由页面的三props属性
    render={
        //这里的props是路由三prop
        props =>
        // 登录对象集合中的登录状态
      fakeAuth.isAuthenticated ? (
          // 为true 就显示该组件
        <Component {...props} />
      ) : (
        <Redirect
        // 登录状态为false时重定向到登录页面
          to={{
            pathname: "/login",
            state: { from: props.location }
          }}
        />
      )
    }
  />
);

const Public = () => <h3>公共页面</h3>;
const Protected = () => <h3>需要登录的页面</h3>;
//登录页面
class Login extends React.Component {
  state = {
      // 登录状态
    redirectToReferrer: false
  };

  login = () => {
      // 点击登录时触发登录方法
    fakeAuth.authenticate(() => {
        // 将redirectToReferrer登录状态转变为true
      this.setState({ redirectToReferrer: true });
    });
  };

  render() {
      // 解构赋值到 from  有传递过来想去的页面就去这个页面   没有的话就去 /
    const { from } = this.props.location.state || { from: { pathname: "/" } };
    const { redirectToReferrer } = this.state;

    // 如果登录状态为true 就重定向到from页面
    if (redirectToReferrer) {
      return <Redirect to={from} />;
    }

    return (
      <div>
        <p>你还没有权限需要先登录 {from.pathname}</p>
        <button onClick={this.login}>登录</button>
      </div>
    );
  }
}

// export default AuthExample;
ReactDOM.render(<AuthExample />, document.getElementById('root'))

相关文章

网友评论

      本文标题:react路由拦截

      本文链接:https://www.haomeiwen.com/subject/lphfoctx.html