Redu 登录状态判断的一些实践

最近一直在写一个React、Redux的前端项目,登录状态验证这一块还是比较头疼的。

我的实践下有三种方式来验证用户登录状态,目前我选择用三种方式一起用在项目里面。

  1. Redux高阶函数验证(High-Order Function)

  2. Actions中间件验证

  3. 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 (                    {this.props.isSignIn == true                        ?                         : null                    }            )        }    }    const mapStateToProps = (state) => ({        path:state.routing.locationBeforeTransitions.pathname,        isSignIn:state.common.isSignIn,        state:state    })    return connect(mapStateToProps)(AuthenticatedComponent);}

你可以把它像这样用在router中:

{ path:'courseCate',component:requireAuthentication(CourseCate)}

目前存在的一些问题:

  1. 高阶函数中传入的最顶层的Component不能再使用connect

  2. 过多的高阶函数生命周期的逻辑难以维护、性能隐患

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)))    }}

目前存在的一些问题:

  1. 虽然可以避免过多的高阶函数函数导致页面性能下降,但是无法很好满足业务逻辑

  2. 验证如果未通过直接阻断当前操作

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'));    }

目前存在的一些问题:

  1. 权限未得到验证时,不会阻断子控件渲染,触发子控件生命周期中的事件

举个例子:
比如父控件中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验证,使用范围就比较狭窄了。

大家雨露均沾

以上是我个人目前的一些小见解,欢迎各位指正和补充哈。

关键字:JavaScript, react.js, Redux, dispatch

版权声明

本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处。如若内容有涉嫌抄袭侵权/违法违规/事实不符,请点击 举报 进行投诉反馈!

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部