根据用户权限渲染react组件

时间:2018-11-02 06:30:49

标签: javascript reactjs

我需要根据用户角色渲染组件

例如: 如果用户是销售人员,他将看到两个按钮。 但是如果他得到支持,他只会看到第二个按钮。

import React from 'react';
import Button from './MyCustomButton';

class App extends React.PureComponent {

  render() {
    return (
      <Grid>
        <Button> // visible only for sales manager
          Action A
        </Button>
        <Button> // visible for support and sales manager
          Action B
        </Button>
      </Grid>
    )
  }
}

我真的很想避免在渲染器中使用if-else语句。保持清洁。

这里是否有一个好的设计或一些有用的工具/装饰器?

我已经在服务器端处理过了,但是我也需要在客户端使用干净的解决方案。

谢谢。

6 个答案:

答案 0 :(得分:5)

您可以将三元语句直接内联到组件树中,如下所示。如果这些布尔表达式的计算结果为false,则react将自动跳过它们。

class App extends React.PureComponent {

  render() {
    const user = this.props.user;
    return (
      <Grid>
        {user.isSalesManager && <Button>
          Action A
        </Button>}
        {(user.isSalesManager || user.isSupport) && <Button>
          Action B
        </Button>}
      </Grid>
    )
  }
}

为此,您需要在道具中获得有关用户角色的信息。

React documentation中了解有关条件渲染的更多信息。

答案 1 :(得分:2)

一种实现此目的的方法是使用Authorizo​​r组件。这将是一个非常简单的功能,可以像平常一样为您进行验证,并且只需检查authLevel。如果您需要调整它以使用您的身份验证模型就可以了。

function Authorizor(props) {
  if (props.authLevel > props.user.authLevel) {
    return null;
  }
  const { ComponentToValidate } = props;
  return <ComponentToValidate {...props} />;
}

然后用法就像

<Authorizor authLevel={1} ComponentToValidate={Button} {...this.props} />

在您的示例中,看起来像这样。

class App extends React.PureComponent {

  render() {
    return (
      <Grid>
        <Authorizor authLevel={2} ComponentToValidate={Button} label="Action A" onClick={this.handleActionAThingy} {...this.props} />
        <Authorizor authLevel={1} ComponentToValidate={Button} label="Action B" onClick={this.handleActionBThingy} {...this.props} />
      </Grid>
    )
  }
}

答案 2 :(得分:1)

短代码

 render() {   
      const button1 = <Button>Action A</Button>; // visible only for sales manager
      const button2 = <Button>Action B</Button>; // visible for support and sales manager

      return (
         <Grid>
           {[user.type === 'salesManager' ? button1 : null, button2]}
         </Grid>
      )
 }

答案 3 :(得分:0)

在这种情况下,我通常会像下面这样使用

render(){
var buttonADiv = <Button> // visible only for sales manager
          Action A
        </Button> ;

var buttonBDiv = <Button> // visible for support and sales manager
          Action B
        </Button> ;

var rows = [];

if(user === 'sales'){
    rows.push(buttonADiv);
    rows.push(buttonBDiv);
}
else if(user === 'support'){
    rows.push(buttonBDiv);
}

return (
      <Grid>
        {rows}
      </Grid>
    )
}

答案 4 :(得分:0)

import React from 'react';
import Button from './MyCustomButton';

class App extends React.PureComponent {

   render() {
      if(user.type = 1){
      return (

      );
      }
      else if(user.type = 2){
      return (

     );
     }
  }
}

答案 5 :(得分:0)

如果只是“更干净”的外观而不缺少条件(因为您必须将其放在某个地方),则可以创建简单的可重用组件:

const Visibility = ({ isVisible, children }) => (
  isVisible ? React.Children.only(children) : null;
)

并像这样使用它

      <Grid>
        <Visibility isVisible={user.isSalesManager}>
          <Button> // visible only for sales manager
            Action A
          </Button>
        </Visibility>
        <Visibility isVisible={user.isSalesManager || user.isSupport}>
          <Button> // visible for support and sales manager
            Action B
          </Button>
        </Visibility>
      </Grid>

在不了解您的应用程序体系结构的情况下很难提出更好的解决方案,但是如果您将用户角色保留在可以从任何地方(redux,上下文等)访问的某种存储中,则可以创建非常相似的组件来接受查看其子级所需的角色(假设是字符串数组),以及可能的某种描述符(如alloneOf等(如果您的权限系统更复杂的话),并且组件本身从中获取所需的数据全球商店,并将其与获得的道具进行比较。如果那是您的用例,我可以提供示例。