我创建了一个名为labeledElement
的组件,它基本上只生成
<label {...props}>
<span class="label">{props.label}</span>
{props.children}
</label>
但是,如果子项包含多个输入或按钮,则会出现问题,因为标签会传播点击次数并将焦点放在子项上。在这种情况下,我想使用div
而不是标签。
我的render
方法是否可以分析子项,查看是否有多个子匹配'button input textarea select'
,并根据此输出标签或div?
我对如何一起破解它有一些想法,但所有这些都需要连接到componentDidMount
,检查DOM并调整状态,这似乎是错误的做法的东西。
答案 0 :(得分:5)
你可以递归迭代这样的孩子:
function visitReactElements(element, callback, depth=0) => {
if (!element || !element.props) return;
callback(element, depth);
React.Children.forEach(element.props.children, (element) => {
visitReactElements(element, callback, depth + 1);
});
}
你走上了一条简单反应的道路,将它扭曲成一个复杂的魔法野兽。谨慎行事。
答案 1 :(得分:1)
答案 2 :(得分:1)
我已经建立了一个小型库来处理React.Children结构,您可以执行深度查找以查看是否有一个或多个匹配的标记。
这是图书馆: https://github.com/fernandopasik/react-children-utilities
你可以像这样使用它:
import React from 'react';
import Children from 'react-children-utilities';
function labeledElement(props) {
const hasTags = !!Children.deepFind(props.children, child => ['button', 'input', 'textarea', 'select'].includes(child.type));
const Element = hasTags ? 'div' : 'label';
return (
<Element {...props}>
<span class="label">{props.label}</span>
{props.children}
</Element>
);
}
答案 3 :(得分:1)
对接受的答案略有改动:
w3wp.exe