想必大家在使用react-router的時候,有的組件是需要登錄才能訪問的(private),有的是開放的(public)
現在給大家介紹一下我的實現方式(僅供參考,如有更好的思路,歡迎在評論區回復)
1.第一種封裝一個私有路由
這是我的路由配置,Route大家都知道。不用多講。PrivateRoute 這個是我自己封裝的代碼如下:
PrivateRoute.jsx
import React from 'react';
import {Route,Redirect,withRouter} from 'react-router-dom';
import PropTypes from 'prop-types';
import storage from 'utils/storage.js';
//私有路由,只有登錄的用戶才能訪問
class PrivateRoute extends React.Component{
componentWillMount(){
let isAuthenticated = storage.getItem("token") ? true :false;
this.setState({isAuthenticated:isAuthenticated})
if(!isAuthenticated){
const {history} = this.props;
setTimeout(() => {
history.replace("/login");
}, 1000)
}
}
render(){
let { component: Component,path="/",exact=false,strict=false} = this.props;
return this.state.isAuthenticated ? (
<Route path={path} exact={exact} strict={strict} render={(props)=>( <Component {...props} /> )} />
) : ("請重新登錄");
}
}
PrivateRoute.propTypes ={
path:PropTypes.string.isRequired,
exact:PropTypes.bool,
strict:PropTypes.bool,
component:PropTypes.func.isRequired
}
export default withRouter(PrivateRoute);
使用:
.......
import React from 'react';
import {BrowserRouter as Router , HashRouter , Route,Link,Switch ,withRouter} from 'react-router-dom';
import {syncHistoryWithStore} from 'react-router-redux'
import reducer from '../reducers/index.js';
import Home from 'container/Home.jsx';
import Login from 'container/Login.jsx';
import Regist from 'container/Regist';
import PrivateRoute from 'component/common/PrivateRoute.jsx';
.......
<Route {...props} path="/login" component={Login} />
<Route {...props} path="/regist" component={Regist} />
<PrivateRoute path="/home" component={Home} />
<Route {...props} component={Login} />
代碼很簡單,仔細看一下就明白。這里的PrivateRoute 屬性接口和 Route基本類似。我這里只是提供一種思路,大家可以根據自己的業務添加自己的特色。
- 第二種是使用高階組件。
高階組件(HOC)是react中對組件邏輯進行重用的高級技術。但高階組件本身并不是React API。它只是一種模式,這種模式是由react自身的組合性質必然產生的。具體而言,高階組件就是一個函數,且該函數接受一個組件作為參數,并返回一個新的組件。
現在知道了高階組件是什么,現在我們就用該思路來做一個高階私有路由 HocPrivateRoute代碼如下
HocPrivateRoute.jsx
import React from 'react';
import {Route,Redirect,withRouter} from 'react-router-dom';
import PropTypes from 'prop-types';
import storage from 'utils/storage.js';
function withHocPrivateRoute(WrappedComponent,hocProps){
if(!!!WrappedComponent){
throw new Error("缺少組件參數");
return false;
}
//withRouter 也是一個高階組件 傳遞 history
return withRouter(
class extends React.Component{
constructor(props) {
super(props);
}
componentWillMount(){
let isAuthenticated = storage.getItem("token") ? true :false;
this.setState({isAuthenticated:isAuthenticated})
if(!isAuthenticated){
const {history} = this.props;
setTimeout(() => {
history.replace("/login");
}, 1000)
}
}
render(){
return this.state.isAuthenticated ? (
<WrappedComponent {...hocProps} />
) : ("請重新登錄");
}
}
)
}
export default withHocPrivateRoute;
使用:
...
import React from 'react';
import {BrowserRouter as Router , HashRouter , Route,Link,Switch ,withRouter} from 'react-router-dom';
import {syncHistoryWithStore} from 'react-router-redux'
import reducer from '../reducers/index.js';
import Home from 'container/Home.jsx';
import Login from 'container/Login.jsx';
import Regist from 'container/Regist';
//import PrivateRoute from 'component/common/PrivateRoute.jsx';
import HocPrivateRoute from 'component/common/HocPrivateRoute.jsx';
const PrivateRoute = HocPrivateRoute(Route);
...
<Switch>
<Route {...props} path="/login" component={Login} />
<Route {...props} path="/regist" component={Regist} />
<PrivateRoute path="/home" component={Home} />
<Route {...props} component={Login} />
</Switch>
總結:
細心的同學會發現,其實代碼很相似,但是模式確實不一樣。這也從側門說明js function 和 class 本質是一樣的。
喜歡的朋友給個贊?。。?!