近来一直在写一个React、Redux的前端项目,登录状况考证这一块照样比较头疼的。
我的实践下有三种体式格局来考证用户登录状况,现在我挑选用三种体式格局一同用在项目内里。
Redux高阶函数考证(High-Order Function)
Actions中心件考证
Component WillMount 考证
之所以用三种体式格局一同是因为Redux高阶函数在机能调优的时刻并非迥殊轻易。
Redux高阶函数考证
//把须要登录状况考证的Component传入到这个高阶函数中
export function requireAuthentication(Component) {
class AuthenticatedComponent extends Component {
constructor(props) {
super(props)
}
//只在初次Mount时来考证权限
componentWillMount() {
this.checkAuth();
}
checkAuth(){
const {path,isSignIn,dispatch}=this.props;
if(!isSignIn){
//没有登录
//纪录当前页面path
//跳转到SignIn Page处置惩罚登录 登录完成够会跳回当前页面
dispatch(CommonActions.setNextUrl(path))
browserHistory.push('/sign');
}
}
render() {
console.log('auth render')
return (
<div>
{this.props.isSignIn == true
? <Component {...this.props}/>
: null
}
</div>
)
}
}
const mapStateToProps = (state) => ({
path:state.routing.locationBeforeTransitions.pathname,
isSignIn:state.common.isSignIn,
state:state
})
return connect(mapStateToProps)(AuthenticatedComponent);
}
你能够把它像如许用在router中:
{ path:'courseCate',component:requireAuthentication(CourseCate)}
现在存在的一些问题:
高阶函数中传入的最顶层的Component不能再运用connect
过量的高阶函数生命周期的逻辑难以保护、机能隐患
Actions中心件考证
export function checkAuth(nextUrl,nextFn) {
return (dispatch,getState)=>{
//检测用户登录状况
if(!getState().common.isSignIn){
//没有登录 纪录当前path
//跳转到sign page 登录完成后 跳转返来
dispatch(setNextUrl(nextUrl));
pushUrl('/sign');//封装了 browserHistory.push(url)
}else{
//经由过程考证后 实行下一个Fn
dispatch(nextFn);
}
}
}
你能够像如许用在你的Actions中
export function fetchFoo(url,conf) {
return (dispatch,getState) => {
if(shouldFetchFoo(getState())){
dispatch(requestFetchFoo());
return fetch(url,conf)
.then(res=>res.json())
.then(json=>{
...
})
}
}
}
export function needFetchFoo(nextUrl,url,conf){
retrun (dispatch)=>{
dispatch(checkAuth(nextUrl,fetchFoo(url,conf)))
}
}
现在存在的一些问题:
虽然能够防止过量的高阶函数函数致使页面机能下落,然则没法很好满足营业逻辑
考证假如未经由过程直接阻断当前操纵
Component WillMount 考证
这基本上能够认为是Actions中心考证的一种变种
export function checkAuthWithoutNextFn(nextUrl) {
return (dispatch,getState)=>{
//check if user sign in
if(!getState().common.isSignIn){
//if not set the nexturl
//and push url to sign page
dispatch(setNextUrl(nextUrl));
pushUrl('/sign');
}
}
}
你能够像如许把他用在Component WillMount事宜中
componentWillMount(){
const {dispatch} = this.props;
dispatch(CommonActions.checkAuthWithoutNextFn('/coursecate'));
}
现在存在的一些问题:
权限未获得考证时,不会阻断子控件衬着,触发子控件生命周期中的事宜
举个例子:
比方父控件中componetWillDidMount中挪用该要领推断用户登录状况
fatherComponet.js
componentWillMount(){
const {dispatch} = this.props;
dispatch(CommonActions.checkAuthWithoutNextFn('/coursecate'));
}
但是子控件componentWillMount中有一个fetch是须要权限考证(此时父控件中并没有阻断子控件衬着,在父控件正在考证权限的同时,子控件的fetch实行了。高阶函数能够阻断子控件衬着)的。
虽然衬着递次是fatherComponet->childComponet
然则childComponet里的componentWillMount也是触发了(也就是说,在未考证登录状况下就触发了fetch),可能会形成一些不必要的要求。
我现在的处置惩罚体式格局:在子控件ComponentWillMount的fetch中到场一个shouldFetch()举行要求前推断。
总结
1.高阶函数合适用在:子控件须要肯定权限后衬着
2.actions中心件合适:无状况页面中的登录状况推断
3.component考证,运用范围就比较狭小了。
人人雨露均沾
以上是我个人现在的一些小看法,迎接列位指正和补充哈。