首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >如何实现React组件的鉴权功能

如何实现React组件的鉴权功能

作者头像
挥刀北上
发布2020-06-16 15:31:33
2.8K0
发布2020-06-16 15:31:33
举报
文章被收录于专栏:Node.js开发Node.js开发

权限控制算是软件项目中的常用功能了。在前端项目开发过程中,权限控制一般分为两个维度:页面级别和页面元素级别。

今天我们来聊一下在React项目中如何实现页面元素级别的鉴权功能。

前面有两篇文章分别介绍了React的高阶组件的使用方法React的Render Prop的使用方法,即各自优缺点。

接下来我们用React的高阶组件方式和React的Render Prop方式分别实现一下React组件的鉴权功能。

在React项目中,不同的用户权限所能看到的组件是不同的,例如管理者与普通用户,登录同一个网站,看到的内容是不同的。

假设我们项目某个页面中有两个组件List组件和Header组件,这两个组件需要根据用户的权限显示不同的内容,该如何实现呢,代码如下:

import React,{Component} from 'react';

// 模拟获取用户权限
function getAuthor(){
    return new Promise((resolve,rekect)=>{
      setTimeout(()=>{
        let index = Math.round(1-Math.random());
        let author = ['admin','user'][index]
          resolve(author)
      },1000)
    })
  }

class List extends Component{
    state = {author:''}
    async componentDidMount(){
      // 在生命周期中获取用户权限;
        let author = await getAuthor();
        this.setState({author})
    }
    render(){
      // 在render中根据用户权限显示不同的内容
        const {author} = this.state
        if(author==='admin'){
            return <div>管理员</div>
          }else{
            return <div>普通户</div>
          }
    }
}


class Header extends Component{
  state = {author:''}
    async componentDidMount(){
      // 在生命周期中获取用户权限;
        let author = await getAuthor();
        this.setState({author})
    }
    render(){
      // 在render中根据用户权限显示不同的内容
        const {author} = this.state
        if(author==='admin'){
            return <div>管理员</div>
          }else{
            return <div>普通户</div>
          }
    }
}


function App() {
  return (
    <div className="App">
        <List />
        <Header/>
    </div>
  );
}

export default App;

阅读源码,我们在List组件和Header组件中都进行了获取用户权限的操作,如果项目中需要鉴权的组件比较多,那么所有需要鉴权的组件都需要去添加这部分代码,实在是冗余,其实这部分代码是可以被提取出来的。

首先我们使用React的高阶组件的方式来优化代码,在此之前我们要清楚什么是高阶组件,高阶组件本身是一个函数,其内部封装了一些通用逻辑,其参数为组件,其调用结果返回一个新的组件,清楚高阶组件的这些特性之后就能轻松写出高阶组件了,代码如下:

import React,{Component} from 'react';

//模拟获取用户权限
function getAuthor(){
  return new Promise((resolve,rekect)=>{
    setTimeout(()=>{
      let index = Math.round(1-Math.random());
      let author = ['admin','user'][index]
        resolve(author)
    },1000)
  })
}

// 需要鉴权的组件,将权限提取为参数
 function List(author){
      if(author==='admin'){
        return <div>管理员</div>
      }else{
        return <div>普通户</div>
      }
}

// 需要鉴权的组件,将权限提取为参数
function Header(author){
  if(author==='admin'){
    return <div>管理员</div>
  }else{
    return <div>普通户</div>
  }
}

// 1、定义高阶组件本事是一个函数
// 2、参数是一个组件
function AuthorHoc(Com){

  // 3、返回结果是一个组件
  return class extends Component{
    constructor(props){
      super(props)
    }
    // 4、内部封装通用逻辑,获取用户权限
    state={author:''}
    async componentDidMount(){
      let author = await getAuthor();
      this.setState({author})
    }
    render(){
      return <div>
        <h1>wrap</h1>
        {/* 5、调用传递的组件,
        并将高阶组件获取的权限
        传递到目标组件*/}
        <Com author={this.state.author} {...prop}/>
      </div>
    }
  }
}
let Newlist = AuthorHoc(List);
let NewHeader = AuthorHoc(Header);

function App() {
  return (
    <div className="App">
      <Newlist/>
      <NewHeader/>
    </div>
  );
}
export default App;

仔细阅读代码,代码中主要进行了如下几部操作:

第一步,我们将组件中的通用逻辑提取到了高阶组件中,通用逻辑指的是获取用户权限这部分代码。

第二步,调用高阶组件这个函数,并且将需要被鉴权的组件作为参数,调用结果得到了新的组件,NewList组件与NewHeader组件。这两个新组件可以直接使用,其内部进行了鉴权,这便是高阶组件的使用方式。

接下来我们用React的 render prop方式来优化代码。先来看下官方解释:

“render prop” 是指一种在 React 组件之间使用一个值为函数的 prop 共享代码的简单技术。 具有 render prop 的组件接受一个函数,该函数返回一个 React 元素并调用它而不是实现自己的渲染逻辑。 https://react.docschina.org/docs/render-props.html

用大白话来讲,就是将组件中的通用逻辑提取到一个公共组件中,这个公共组件渲染的内容由其参数render决定,render这个参数是一个函数,这个函数调用会返回React组件,从而实现定制化渲染。看代码:

import React,{Component} from 'react';

function getAuthor(){
  return new Promise((resolve,rekect)=>{
    setTimeout(()=>{
      let index = Math.round(1-Math.random());
      let author = ['admin','user'][index]
        resolve(author)
    },1000)
  })
}

 function List(author){
      if(author==='admin'){
        return <div>管理员</div>
      }else{
        return <div>普通户</div>
      }
}

function Header(author){
  if(author==='admin'){
    return <div>管理员</div>
  }else{
    return <div>普通户</div>
  }
}

class AuthorProp extends Component{
    constructor(props){
        super(props)
    }
    // 抽离公共逻辑
    state = {author:''}
    async componentDidMount(){
        let author = await getAuthor();
        this.setState({author})
    }
    render(){
        return <div>
            <h1>prop</h1>
            {/* 调用render,render的返回值是一个组件,
            这个组件决定渲染内容
            */}
            {this.props.render(this.state.author)}
        </div>
    }
}

function App() {
  return (
    <div className="App">
      {/* render本质是个函数,
      其返回值是一个React组件 */}
      <AuthorProp render={prop=>List(prop)} />
    </div>
  );
}
export default App;

阅读代码,我们将通用逻辑封装到了一个公共组件中,这个公共组件在调用时必须传递一个render参数(也可以换成其他单词),render参数的本质是一个函数,这个函数在公共组件内部调用返回一个React组件,返回的React组件决定渲染什么内容。

在我们的案例中,render函数返回的组件要依赖公共组件获取的用户权限author,所以我们通过render函数将author传递给了需要被鉴权的组件。

这里的render像是一个特殊的盒子,盒子里面装的是需要被渲染的组件,这个盒子会在公共组件内部被打开,打开时可以传递参数author,author会传递到组件中,组件根据author渲染不同的内容。

仔细对比两种方式,使用render prop相较于高阶组件,项目中并未新增组件,也不存在组件嵌套过深的问题,个人感觉比较灵活。

以上便是使用React的高阶组件方式和React的Render Prop方式分别实现一下React组件的鉴权功能,如果你有什么建议或者想法欢迎留言。

下篇文章用React的自定义hook函数来实现组件的鉴权功能。

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

本文分享自 nodejs全栈开发 微信公众号,前往查看

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档