Reactjs 在render方法中递归检查组件的子级

Reactjs 在render方法中递归检查组件的子级,reactjs,Reactjs,我创建了一个名为labeledElement的组件,它基本上只生成 <label {...props}> <span class="label">{props.label}</span> {props.children} </label> 但是,如果子项包含多个输入或按钮,则会出现问题,因为标签会将单击和焦点传播给子项。在这个场景中,我希望使用div而不是标签 在我的render方法中是否可以分析子项,查看是否有多个子项匹配“bu

我创建了一个名为labeledElement的组件,它基本上只生成

<label {...props}>
    <span class="label">{props.label}</span>
    {props.children}
</label>
但是,如果子项包含多个输入或按钮,则会出现问题,因为标签会将单击和焦点传播给子项。在这个场景中,我希望使用div而不是标签

在我的render方法中是否可以分析子项,查看是否有多个子项匹配“button input textarea select”,并根据此输出创建标签或div


我有一些想法如何将其整合在一起,但所有这些都需要连接到componentDidMount,检查DOM并调整状态,这似乎绝对是错误的做法。

我不知道我是否正确理解您的问题,但我想您要找的是这个

您可以简单地计算/检查您的子道具并正确渲染


希望这有帮助

您可以像这样递归地迭代子对象:

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);
  });
}
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>
    );
}

你走的是一条需要简单反应并将其扭曲成复杂的魔法野兽的道路。小心操作。

我制作了一个小库来处理React.Children结构,您可以执行深度查找以查看是否有一个或多个匹配的标记

这是图书馆:

您可以这样使用它:

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);
  });
}
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>
    );
}

对公认的答案有点扭曲:

函数visitReactElementschildren,回调,深度=0{ 如果!孩子们回来; 回拨儿童,深度; React.Children.forEachchildren,el=>{ visitReactElementsel.children,回调,深度+1; }; } const WrapperComponent={children}=>{ useEffect=>{ visitReactElementschildren,console.log; },[儿童]; 返回{children}; };
你能从labeledElement的父级传入一个额外的道具吗?@rossta是的,这就是我现在正在做的,但是Reactjs应该已经有了所有的信息,这个决定必须基于{this.props.children}返回的ReactElement集合上的映射和检查对象属性如何?你也许可以从孩子们的类型和道具中得到你想要的东西。@rossta这也是我的第一个想法,但这似乎只向我展示了一个层次的深度。但话说回来,可能还有更进一步的路要走,我只是不知道怎么走。你能在评论中澄清什么是不清楚的吗?我表达了这个问题,并给出了一个具体的例子——我真的不知道如何问得更切题。问题不是我不知道如果我不使用jsx怎么做,所以这很容易,而是我不知道如何递归地检查所有的孩子。这是调用render方法时react应该拥有的所有信息,但是我如何提取它?我不知道props.children中的数据结构如何,也无法帮助您检查它,所以我假设您询问如何相应地渲染它。当我调用myComponent{},label{},您好,输入标签调用的结果将传递到myComponent。label的结果是一个ReactElement,它是该组件发生了什么的描述符。这包括所有儿童。因此,所有这些数据都必须可用于渲染方法。我真的不知道该怎么做。你有没有得到react tools的chrome扩展?它允许您单击任何dom元素并查看它们的react-props/state。谢谢,向上投票。这个问题是在hooks之前创建的,所以感觉它可能对其他人有用