React-router 路由守卫

作者: Viewwei | 来源:发表于2021-01-12 15:14 被阅读0次
  • 什么叫路由守卫
    路由在跳转之前做一些验证,比如只有登录之后才能进入用户界面。
  • 技术要点
    react-router react-redux react-thunk(react-saga)
  • 实现功能
    模仿登录,只有用户输入123,点击登录之后才能进入user.js界面
  • 实现思路
    实现的思路只要是通过高阶组件(hoc)把user封装一下,在封装的组件中,拿到isLogin是否是true,如果是true的话重定向到user组件,如果是false,则显示登录界面
  1. 创建user.js文件(基本组件)和login.js登录界面
const User = () =>{
    
    return (
        <div>userssssssssssssssssssssss</div>
    )
}
export default User

2.创建高阶组件Provide .js

import { Redirect, Route } from "react-router"
import { useSelector } from "react-redux"

function PrivateRoute (props) {
   const {component:Component,...rest}  =props
   const data = useSelector(state=>state.user) //这个地方也可以使用connect获取值
  const {isLogin} = data
    return (
        <Route
        {...rest}
        render={props =>
          isLogin ? (
            <Component {...props} />
          ) : (
            <Redirect
              to={{pathname: "/login", state: {from: props.location.pathname}}}
            />
          )
        }
      />
    )
  
    
}
export default PrivateRoute
  1. 创建路由文件
import user from './smallPage/user'
import Login from './smallPage/login'
import Provide from './PrivateRoute'
import { BrowserRouter as Router, Route, Link, Switch } from "react-router-dom";
// import a from 'react'
const Index = () => {
    return (
        <div>
            <Router>
                <div>
                <Link to="/">首页</Link>
                <Link to="/two">two</Link>
                <Link to="/third">third</Link>
                </div>
                <Switch>
                    <Provide exact path="/" component={user}></Provide>
                </Switch>
            </Router>
        </div>
    )
}
export default Index
  1. 使用react-redux,创建index.js和reducer.js
    index.js
import {applyMiddleware, createStore,combineReducers} from 'redux'
import thunk from "redux-thunk";
import {loginReducer} from './loginReducer'
import rootSaga from "../soga/rootSaga";
import createSagaMiddleware from "redux-saga";
const sagaMiddleware  = createSagaMiddleware()
const store = createStore(combineReducers(
    {user:loginReducer}),
    // applyMiddleware(sagaMiddleware)
    applyMiddleware(thunk)
    )
    // sagaMiddleware.run(rootSaga);
export default store

reducer.js

const userInit = {
    isLogin: false,
    userInfo: {id: null, name: "", score: 0},
    loading: false,
    err: {msg: ""}
  };
  
  // 定义用户基本信息修改规则
  export const loginReducer = (state = {...userInit}, {type, payload}) => {
    switch (type) {
      case "REQUEST":
        return {...state, loading: true};
      case "LOGIN_SUCCESS":
        return {...state, isLogin: true, loading: false, userInfo: {...payload}};
      case "LOGIN_FAILURE":
        return {...state, ...userInit, ...payload};
      case "LOGOUT_SUCCESS":
        return {...state, isLogin: false, loading: false};
      default:
        return state;
    }
  };
  1. 创建登录界面
import { useEffect, useState } from "react"
import { useHistory } from "react-router";
import {useSelector,useDispatch,connect} from 'react-redux'
import {login} from '../../action/index'
const Login = (props) => {
    console.log("props:",props);
    const {isLogin,loginResult} = props
    let history = useHistory()
    if (isLogin){
        history.replace(props.location.state.from) 
    }
    const [state, setState] = useState("")
    const changeValue = e => {
        setState(e.target.value)
    }
    return (
        <div>
            <input value={state|| ""} onChange={e => changeValue(e)} />
            <button onClick={e =>loginResult({name:state}) }>登录</button>
        </div>
    )
}
export default connect(({user}) =>({isLogin:user.isLogin}),{loginResult:login})(Login) 
//react-redux 映射到组件里面,获取redux的值和方法
  1. 在service、login.js文件的写入登录函数
const LoginService = {
    login(userInfo) {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          if (userInfo.name === "123") {
            resolve({id: 123, name: "omg原来是小明"});
          } else {
            reject({err: {msg: "用户名或密码错误"}});
          }
        }, 1000);
      });
    },
    // 获取更多信息
    getMoreUserInfo(userInfo) {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          if (userInfo.id === 123) {
            resolve({...userInfo, score: "100"});
          } else {
            reject({msg: "获取详细信息错误"});
          }
        }, 1000);
      });
    }
  };
  export default LoginService;
  1. 创建action/index.js文件调用登录函数,主要是给login.js文件提供方登录方法
export  const LoginUserClick  = user =>dispatch=>{

    LoginService.login(user).then(res=>{
        getMoreUserInfo(dispatch,res)  
    },err=>{

    })
}
export const getMoreUserInfo = (dispatch, userInfo) => {
  LoginService.getMoreUserInfo(userInfo).then(
    res => {
      dispatch({type: "LOGIN_SUCCESS", payload: res});
    },
    err => {
      dispatch({type: "LOGIN_FAILURE", payload: err});
    }
  );
};

路由守卫就完成了...........

相关文章

网友评论

    本文标题:React-router 路由守卫

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