Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best way to figure out if component is an instance of functional component in React

For a component I'm building I'm recursively looping over its child components using React.Children.map to make modifications to their props. The basic structure is like this:

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

  });
}

Children of Main will have their props modified via recursivelyModifyChildProps and their children will have their props modified, etc. I want to do this unless the child component is an instance of the Main component, in that case it should be returned unmodified. Currently I'm doing this via child.type.name, and this does work. However, this implementation is very bug prone I believe, since everyone could call their component "Main". What is the best (or at least a better) way to figure out that a component is an instance a particular (functional) component, or an instance of itself?

like image 806
Luuuud Avatar asked Sep 17 '25 08:09

Luuuud


1 Answers

You can validate it by comparing the child.type to Main instance which is unique.

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

Edit Q-58851178-childType


A full example of modifying all Main children with skipping the Main instance.

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'));
like image 170
Dennis Vash Avatar answered Sep 19 '25 23:09

Dennis Vash