javascript - 反应父组件从开关/路由中获取渲染元素的计数
问题描述
我正在尝试制作一个组件来呈现其子元素的包装器元素,但是它需要知道元素是否被呈现为其子元素。我有忽略 Switch、Route 和组件子组件的功能。
const MAX_CHILDREN_TRAVERS = 8;
const NON_RENDABLE_ELEMENTS = ['Switch','Switch()','Route','LeftPanel','MainPanel','RightPanel'];
function findByType (children, component) {
return children === undefined || children.length === 0 ? null : children.filter(child => component.name === getElmType(child));
};
function getElmType(elm) {
return elm && elm.type && (elm.type.displayName || elm.type.name);
}
function getRendableChildren(elm) {
const checkChildren = (e, count) => {
if(count>MAX_CHILDREN_TRAVERS) {
return e;
}
return NON_RENDABLE_ELEMENTS.includes(getElmType(e)) ? checkChildren(e.props.children,count++) : e;
};
return elm.length > 0 ? elm.map(elm => checkChildren(elm,0)) : elm;
}
function renderPanel({ children, panel, className}) {
const myPanel = findByType(children, panel);
return getRendableChildren(myPanel).length > 0 || myPanel === null || myPanel.length === 0 ? null : <div className={className}>{myPanel.map(el => el.props.children)}</div>;
};
export {
findByType,
renderPanel
};
这确实返回忽略列出元素的子元素数组。但是,它也会为我提供路径中未在该路径上呈现的元素。我只想要在该路线上呈现的元素列表。
getRendableChildren() 应该遍历直到找到可读元素并返回它们。虽然它适用于忽略和传递我想忽略的列出的元素。无论路由是否处于活动状态,它都可以看到所有路由中的所有子元素。
解决方案
我发现如果我使用 window.location.pathname 并将其检查到 Route e.props.path。我可以确认路线是否处于活动状态并根据需要排除。
import React from 'react';
const MAX_CHILDREN_TRAVERS = 8;
const NON_RENDABLE_ELEMENTS = ['Switch','Switch()','LeftPanel','MainPanel','RightPanel'];
const IS_ROUTE = ['Route','Route()'];
function findByType (children, component) {
return children === undefined || children.length === 0 ? null : children.filter(child => component.name === getElmType(child));
};
function getElmType(elm) {
return elm && elm.type && (elm.type.displayName || elm.type.name);
}
function getRendableChildren(elm) {
const checkChildren = (e, count) => {
if(count>MAX_CHILDREN_TRAVERS) {
return e;
}
const elmType = getElmType(e);
if(IS_ROUTE.includes(elmType)){
const lo = window.location.pathname.split('/').filter(a => a.length);
const pa = e.props.path.split('/').filter(a => a.length);
return pa.every((e,i) => e === lo[i]) ? [...e.props.children] : null;
}
return NON_RENDABLE_ELEMENTS.includes(elmType) ? checkChildren(e.props.children,count++) : e;
};
return elm.length > 0 ? elm.map(elm => checkChildren(elm,0))[0] : elm;
}
function renderPanel({ children, panel, Wrapper, props}) {
const myPanel = findByType(children, panel);
return getRendableChildren(myPanel) === null || getRendableChildren(myPanel).length === 0 || myPanel === null || myPanel.length === 0 ? null : React.createElement(Wrapper, props, myPanel.map(el => el.props.children));
};
export {
findByType,
renderPanel
};
推荐阅读
- qt - QML:使用 Grid 模拟 GridView/ListView cacheBuffer
- javascript - createElement 创建无限循环
- ruby-on-rails - Capybara::ElementNotFound:找不到可见的选择框
- ios - IBOutlet 因 EXC_BAD_ACCESS 而崩溃,即使不是 nil
- php - “未定义索引:名称” Laravel 5.7 控制器
- python - 如何将 yticks 添加到 pyplot 中的一个特定点?
- sql-server - 设置从某个值开始的自动增量值 T-SQL
- mysql - Drupal - PDOException:SQLSTATE [42S02]
- java - java- SDK 版本和 Vm 选项
- java - 为什么 outputStream 没有 inputStream 就不能工作?