前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >闲话react路由守卫

闲话react路由守卫

作者头像
一粒小麦
发布2019-07-30 15:30:49
2.3K0
发布2019-07-30 15:30:49
举报
文章被收录于专栏:一Li小麦一Li小麦

老外做生意的思路和中国人不太一样,中国人喜欢便宜货,比如说买相机,期望什么都给你配好,还附送一大堆东西。而老外发给你的货干干净净,所谓贵的要命名牌也只不过是廉价的环保纸盒(摔不坏即可)。一分钱也不少赚你,同理一分钟钱也不多赚你。

在贸易战的大背景下,你可能不大认同这点。但就程序开发这点来说体会特别特别深。作为中国人写的框架比如vue,thinkjs等。用起来特别傻瓜式。而那些由“不存在的公司”Google,facebook开发的react,angular之流。写起来是真的高冷。而无可否认乃至包括尤雨溪也承认,vue参考了react的诸多东西。

需求

现有需求如左:登录判断。

前后端的撕逼似乎还没完,jwt方案扯了如同没说。现在说,在每个需要鉴权的页面做登录态请求。通过了,才能做访问。

看到这个需求,我真的羞于做这样的事情。好好的一个SPA应用。硬生生做成web1.0时代的感觉,真是日了热比娅了!这TM后端做的东西我来搞!

但面向百度遍了一波程序,发现这种需求在中国人中间还贼tm多。心情也渐渐平复。其实无论是token验证还是这种恶心的验证方式。都是用高阶组件来实现的。

先简单介绍下高阶组件。

react高阶组件(HOC)

react有一个著名的公式:

代码语言:javascript
复制
UI或页面page=f(state)

而对对于HOC:

代码语言:javascript
复制
const EnhancedComponent = highOrderComponent(WrappedComponent);

组件是把 props 转化成 UI,而高阶组件是把一个组件转化成另外一个组件。

由此可得,高阶组件不是什么react的功能,它只是一个函数,接收一个组件,然后返回一个新的组件。

既然是函数,那就可以有参数,有返回值。从上面可以看出,这个函数接收一个组件 WrappedComponent 作为参数 ,返回加工过的新组件 EnhancedComponent。其实高阶组件就是设计模式里的装饰者模式

高阶组件你可以理解为一台相机裸机。 你得给他装个牛逼镜头,配个滤镜。装个挂带。然后才能带着出去装逼。 (冠希哥设计对白:我要开始装逼了)

下面是一个简单的高阶组件:

代码语言:javascript
复制
import React, { Component } from 'react';

export default (WrappedComponent) => {
  return class EnhancedComponent extends Component {
    // do something
    render() {
      return <WrappedComponent />;
    }
  }
}

从上面的代码可以看出,我们可以对传入的原始组件 WrappedComponent 做一些你想要的操作(比如操作 props,提取 state,给原始组件包裹其他元素等),从而加工出你想要的组件 EnhancedComponent 。把通用的逻辑放在高阶组件中,对组件实现一致的处理,从而实现代码的复用。

守卫

vue的思路是:你告诉我想拍什么效果,我帮你实现哟。 react的思路是:给你一台裸机,去创造世界吧。造的怎么样看你的水平。

https://reacttraining.com/react-router/web/example/auth-workflow

react的路由守卫在4.0之前是有一个类似 beforeEach的前置钩子。但4.0之后删了。作者的理由是:删了更自由。

现在就采用高阶组件的形式来体现了:

代码语言:javascript
复制
const PrivateRoute = ({ component: Component, ...rest }) => (
    class Guard extends Component {
        constructor(props) {
            super(props)
            this.state = {
                auth: false,     // 表示是否认证通过
                hasAuthed: false,  // 表示是否向服务器发送过认证请求
                role:null //教师或学生
            };
        }

        componentDidMount() {
            //向服务器发送认证请求,result表示认证是否成功
            Http.get(Api.isLogin, (msg) => {
                console.log('msg',msg.errno)
                if (msg.errno == 0) {

                    if (msg.data.result.role) {
                        //老师
                        this.setState({
                            auth:true,
                            hasAuthed:true,
                            role:'teacher'
                        })
                    } else {
                        //学生
                        this.setState({
                            auth:true,
                            hasAuthed:true,
                            role:'student'
                        })
                    }

                } else {
                    // alert(msg.errmsg)
                    this.setState({
                        hasAuthed:true,
                    })
                }
            })
        }

        render() {
            // 初始渲染时,尚未向服务器发送认证请求,因此不渲染元素
            console.log(this.state.auth)
            if (!this.state.hasAuthed) {
                return null;
            }else{

                return <Route {...rest} render={props => (
                    this.state.auth ? (
                        <Component {...props}/>
                    ) : (
                            <Redirect to={{
                                pathname: '/login',
                                state: { from: props.location }
                            }} />
                        )
                )} />
            }

        }
    }
)

注意:if(!this.state.hasAuthed)肯定会造成白屏。可见这个体验也还真的不怎么样~~。

以上。


本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-07-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 一Li小麦 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 需求
  • react高阶组件(HOC)
  • 守卫
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档