- 什么叫路由守卫
路由在跳转之前做一些验证,比如只有登录之后才能进入用户界面。 - 技术要点
react-router react-redux react-thunk(react-saga) - 实现功能
模仿登录,只有用户输入123,点击登录之后才能进入user.js界面 - 实现思路
实现的思路只要是通过高阶组件(hoc)把user封装一下,在封装的组件中,拿到isLogin是否是true,如果是true的话重定向到user组件,如果是false,则显示登录界面
- 创建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
- 创建路由文件
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
- 使用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;
}
};
- 创建登录界面
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的值和方法
- 在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;
- 创建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});
}
);
};
路由守卫就完成了...........