Children 从 FunctionComponent 返回中断 Parent 呈现逻辑
Children returned from FunctionComponent breaks Parent rendering logic
我创建了一个 FunctionComponent,它应该 return 有条件地包含它所包含的 children。
<Tabs defaultActiveKey='1' type='card' activeKey={'1'}>
<TabPane tab='Tab title' key='1'>
<p>Tab title</p>
</TabPane>
<WrapperComponent>
<TabPane tab='Tab title' key='2'>
<p> Tab title 2 </p>
</TabPane>
</WrapperComponent>
</Tabs>
const WrapperComponent: React.FC<Props> = ({children}) => {
if(true)
return (children)
else
return <></>
}
当包装器 return 是 children 元素时,UI 中断并且无法正确呈现。
标签是从 antd.
导入的
页面渲染结果:
任何使用 antd UI 库中的逻辑渲染的元素都会发生同样的情况。
编辑
我正在寻找一种方法来根据某些条件渲染 child 元素,并在渲染后强制 parent 元素“刷新”UI ,从而重做创建 UI 库组件的逻辑。
我的目标是创建一个组件来验证登录用户是否有权呈现 object。借此,我寻求避免 TSX 文件中逻辑变量的重复,并获得一个更可重用和可组件化的项目架构。
您可以做的是创建一个选项卡列表和 filter-based permission/roles。
const tabs = [
{
key: "1",
tab: "Tab title",
content: <p>Tab title</p>,
permissions: ["admin", "user"],
},
{
key: "2",
tab: "Tab title 2",
content: <p> Tab title 2 </p>,
permissions: ["admin"],
},
];
const WrapperComponent = ({ tabs, role }) => {
return (
<>
{tabs.map(
(tab) =>
tab.permissions.include(role) ? (
<TabPane tab={tab.tab} key={tab.key}>
{tab.content}
</TabPane>
): null
)}
</>
);
};
<Tabs defaultActiveKey="1" type="card" activeKey={"1"}>
<WrapperComponent tabs={tabs} role="admin" />
</Tabs>;
因为您正在尝试模块化代码。将访问控制逻辑移动到单独的 class,比如 ACL
。此 class 不需要是 UI 组件。简单 class 即可。
在您的 UI 组件中使用 class 方法来确定您是否要显示功能。
代码笔 demo
ACL.js
// access controll managment
var ACL = (function () {
var role = "guest";
var getRole = function () {
return role;
};
var init = function () {
//read local storage/ cookies and get role
role = "admin";
};
var hasAccessTo = function (page, feature) {
//do the checking
return role === "admin";
};
// call this after login
init();
return {
init: init,
getRole: getRole,
hasAccessTo: hasAccessTo
};
})();
export default ACL;
在您的 UI 组件中,它可以像这样使用:
import ACL from "./ACL";
// filter based on role
function filter() {
if (ACL.hasAccessTo("tabsPage", "secretTab")) {
return (
<TabPane tab="Secret" key="2">
The access code is: ██████
</TabPane>
);
}
}
const Demo = () => (
<Tabs defaultActiveKey="1">
<TabPane tab="Info" key="1">
Genral info
</TabPane>
/* you can write a separate function to do the filtering */
{filter()}
/* OR use expression like this */
{ACL.hasAccessTo("tabsPage", "secretTab") &&
<TabPane tab="Secret 2" key="3">
secret 2: some secret
</TabPane> }
</Tabs>
您当前的 WrapperComponent
无法正常工作,因为包装标签没有得到正确处理。例如id为rc-tabs-0-tab-null
key 丢失
我创建了一个 FunctionComponent,它应该 return 有条件地包含它所包含的 children。
<Tabs defaultActiveKey='1' type='card' activeKey={'1'}>
<TabPane tab='Tab title' key='1'>
<p>Tab title</p>
</TabPane>
<WrapperComponent>
<TabPane tab='Tab title' key='2'>
<p> Tab title 2 </p>
</TabPane>
</WrapperComponent>
</Tabs>
const WrapperComponent: React.FC<Props> = ({children}) => {
if(true)
return (children)
else
return <></>
}
当包装器 return 是 children 元素时,UI 中断并且无法正确呈现。 标签是从 antd.
导入的页面渲染结果:
任何使用 antd UI 库中的逻辑渲染的元素都会发生同样的情况。
编辑
我正在寻找一种方法来根据某些条件渲染 child 元素,并在渲染后强制 parent 元素“刷新”UI ,从而重做创建 UI 库组件的逻辑。
我的目标是创建一个组件来验证登录用户是否有权呈现 object。借此,我寻求避免 TSX 文件中逻辑变量的重复,并获得一个更可重用和可组件化的项目架构。
您可以做的是创建一个选项卡列表和 filter-based permission/roles。
const tabs = [
{
key: "1",
tab: "Tab title",
content: <p>Tab title</p>,
permissions: ["admin", "user"],
},
{
key: "2",
tab: "Tab title 2",
content: <p> Tab title 2 </p>,
permissions: ["admin"],
},
];
const WrapperComponent = ({ tabs, role }) => {
return (
<>
{tabs.map(
(tab) =>
tab.permissions.include(role) ? (
<TabPane tab={tab.tab} key={tab.key}>
{tab.content}
</TabPane>
): null
)}
</>
);
};
<Tabs defaultActiveKey="1" type="card" activeKey={"1"}>
<WrapperComponent tabs={tabs} role="admin" />
</Tabs>;
因为您正在尝试模块化代码。将访问控制逻辑移动到单独的 class,比如 ACL
。此 class 不需要是 UI 组件。简单 class 即可。
在您的 UI 组件中使用 class 方法来确定您是否要显示功能。
代码笔 demo
ACL.js
// access controll managment
var ACL = (function () {
var role = "guest";
var getRole = function () {
return role;
};
var init = function () {
//read local storage/ cookies and get role
role = "admin";
};
var hasAccessTo = function (page, feature) {
//do the checking
return role === "admin";
};
// call this after login
init();
return {
init: init,
getRole: getRole,
hasAccessTo: hasAccessTo
};
})();
export default ACL;
在您的 UI 组件中,它可以像这样使用:
import ACL from "./ACL";
// filter based on role
function filter() {
if (ACL.hasAccessTo("tabsPage", "secretTab")) {
return (
<TabPane tab="Secret" key="2">
The access code is: ██████
</TabPane>
);
}
}
const Demo = () => (
<Tabs defaultActiveKey="1">
<TabPane tab="Info" key="1">
Genral info
</TabPane>
/* you can write a separate function to do the filtering */
{filter()}
/* OR use expression like this */
{ACL.hasAccessTo("tabsPage", "secretTab") &&
<TabPane tab="Secret 2" key="3">
secret 2: some secret
</TabPane> }
</Tabs>
您当前的 WrapperComponent
无法正常工作,因为包装标签没有得到正确处理。例如id为rc-tabs-0-tab-null
key 丢失