在渲染方法

时间:2015-10-05 19:50:10

标签: reactjs

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

<label {...props}>
    <span class="label">{props.label}</span>
    {props.children}
</label>

但是,如果子项包含多个输入或按钮,则会出现问题,因为标签会传播点击次数并将焦点放在子项上。在这种情况下,我想使用div而不是标签。

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

我对如何一起破解它有一些想法,但所有这些都需要连接到componentDidMount,检查DOM并调整状态,这似乎是错误的做法的东西。

4 个答案:

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

jsbin

你走上了一条简单反应的道路,将它扭曲成一个复杂的魔法野兽。谨慎行事。

答案 1 :(得分:1)

我不知道我是否理解你的问题,但我认为你在寻找的是

https://www.npmjs.com/package/react-if

你可以简单地计算/检查你的儿童道具并正确渲染。

希望这有帮助

答案 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