我需要根据用户角色渲染组件。
例如: 如果用户是销售人员,他将看到两个按钮。 但是如果他得到支持,他只会看到第二个按钮。
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语句。保持清洁。
这里是否有一个好的设计或一些有用的工具/装饰器?
我已经在服务器端处理过了,但是我也需要在客户端使用干净的解决方案。
谢谢。
答案 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)
一种实现此目的的方法是使用Authorizor组件。这将是一个非常简单的功能,可以像平常一样为您进行验证,并且只需检查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,上下文等)访问的某种存储中,则可以创建非常相似的组件来接受查看其子级所需的角色(假设是字符串数组),以及可能的某种描述符(如all
,oneOf
等(如果您的权限系统更复杂的话),并且组件本身从中获取所需的数据全球商店,并将其与获得的道具进行比较。如果那是您的用例,我可以提供示例。