确定组件是否是React中功能组件的实例的最佳方法

时间:2019-11-14 07:06:24

标签: javascript reactjs react-props react-component react-functional-component

对于我要构建的组件,我使用React.Children.map递归地遍历其子组件,以修改其道具。基本结构是这样的:

// main component
const Main = ({ children }) => recursivelyModifyChildProps(children);

// recursive function
function recursivelyModifyChildProps(children) {
  return React.Children.map(children, (child) => {
    // if no valid react element, just return it
    if (!React.isValidElement(child)) {
      return child;
    }

    // check if child isn't a `<Main/>` component
    // not sure about this check
    if (typeof child.type !== 'string' && child.type.name === 'Main') {
      return child;
    }

    const { children, ...restProps } = child.props;

    // do stuff to create new props
    const newProps = { foo: 'bar' };

    // return new element with modified props
    return React.createElement(
      child.type,
      {
        ...restProps,
        ...newProps,
        children: recursivelyModifyChildProps(children)
      }
    );

  });
}

Main的子代将通过recursivelyModifyChildProps修改其道具,其子代将对其道具进行修改,依此类推。除非子项是{{1}的实例,否则我想这样做}组件,在这种情况下,应返回原样。目前,我正在通过Main进行此操作,并且确实可以。但是,我相信此实现非常容易出错,因为每个人都可以将其组件称为“ Main”。找出一个组件是一个特定(功能)组件的实例,还是其本身的实例的最佳(或至少更好)的方法是什么?

1 个答案:

答案 0 :(得分:2)

您可以通过比较唯一的child.typeMain实例来验证它。

if (child.type === Main) {
  return undefined;
}

Edit Q-58851178-childType


通过跳过Main实例来修改所有Main个孩子的完整示例。

import React from 'react';
import ReactDOM from 'react-dom';

const Main = ({ children }) => recursivelyModifyChildProps(children);

function recursivelyModifyChildProps(children) {
  return React.Children.map(children, child => {
    if (!React.isValidElement(child)) {
      return child;
    }

    if (child.type === Main) {
      return undefined;
    }

    const { children, ...restProps } = child.props;
    const newProps = { foo: 'bar' };

    return React.createElement(child.type, {
      ...restProps,
      ...newProps,
      children: recursivelyModifyChildProps(children)
    });
  });
}

const App = () => {
  return (
    <Main>
//       v Main is skipped
      <Main />
      <div>Hello</div>
    </Main>
  );
};

ReactDOM.render(<App />, document.getElementById('root'));