【问题标题】:nesting components with createElement in React yields error在 React 中使用 createElement 嵌套组件会产生错误
【发布时间】:2021-01-03 21:07:41
【问题描述】:

我正在尝试创建一个辅助函数,将传递的元素/组件嵌套为其自身的多个深度的子级。

像这样的

const Chain = nested(4, () => <div />)
return (
  <Chain />
)

应该渲染嵌套 4 层的 div

<div>
  <div>
    <div>
      <div />
    </div>
  </div>
</div>

我是这样在 React 中实现这个功能的。

/** nest the given element in itself of specified depth */
export const nested = (
  depth: number,
  element: () => JSX.Element
): FC<any> => () => {

  let chain = element();
  for (let i = 0; i < depth; i++) {
    chain = React.createElement(
      element().type,
      element().props,
      chain
    );
  }
  return chain;
};

它正确渲染和显示嵌套的 Div,但返回一条我不明白如何更正的错误消息。

Warning: Functions are not valid as a React child. This may happen if you return a Component instead of <Component /> from render. Or maybe you meant to call this function rather than return it.

【问题讨论】:

    标签: reactjs typescript error-handling components jsx


    【解决方案1】:

    这是我解决的解决方案。感谢@senthil balaji 的回答。

    export const NestedTags = (depth: number, childElement: JSX.Element): JSX.Element => {
      if (depth === 1) {
        return (
          <childElement.type {...childElement.props}>
            {childElement}
          </childElement.type>
        );
      }
    
      return NestedTags(
        depth - 1,
        <childElement.type {...childElement.props}>
          {childElement}
        </childElement.type>
      );
    };
    

    并且应该使用在父级中使用的 React Fragment 包装。

    <>
      {NestedTags(5, <div className='segment'><div>)}
    </>
    

    需要注意的是,当像这样传递一个 React 组件类型时它不能嵌套:

    const Test = ({className}: {className: string}) => (
      <a className={className}>hello</a>;
    )
    //...
    return (
      <>
        {NestedTags(5, <Test className='test'/>}
      </>
    )};
    

    【讨论】:

      【解决方案2】:

      尝试使用recursive 解决方案。

      const createInnerElements = (count, childElement) => {
         if (count == 1) {
           return <div>{childElement}</div>
         }
         return createInnerElements(count - 1, <div>{childElement}</div>);
      }
      
      // in your parent component,
      return <>{createInnerElements(4, <></>)}</>
      

      【讨论】:

      • 谢谢!我修改了这个解决方案以使元素类型动态并在下面发布。
      猜你喜欢
      • 2020-12-30
      • 2021-09-06
      • 2022-11-25
      • 2022-07-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多