简体   繁体   中英

How to test a React component with multiple child components?

I cut out all my code to the area of interest (so pardon if the code looks like it's trying to do nothing), but essentially when I pass in a couple <Navbar.Tab comopnent={null}/> into <Navbar></Navbar> and attempt to unit test it using Jest and Enzyme, the React.Children.count can see that there are > 1 children, but when it comes to .type() it cannot understand it and this error is prompted. The component renders fine, I just don't know how to test it.

 Navbar component › Rendered navbar with many non tabs

    TypeError: child.type is not a function

      48 |   if (React.Children.count(children) > 1) {
      49 |     value = children.map(child => {
    > 50 |       isTab = child.type().toLowerCase() !== 'tabs' ? false : isTab;
         |                     ^
      51 |       return child.props;
      52 |     });
      53 |   }

navbar

const Navbar = ({ children, filter }) => {
  let isTab = true;
  let value = null;
  if (React.Children.count(children) > 1) {
    value = children.map(child => {
      isTab = child.type().toLowerCase() !== 'tabs' ? false : isTab;
      return child.props;
    });
  }
  return (
    <>
      {value.map(child => child.component)}
    </>
  )
}

const Tabs = () => {
  return 'tabs';
};
Navbar.Tab = Tabs;
export default Navbar;

navbar.test.js

 test('Rendered navbar with filter', () => {
    const wrapper = mount(
      <Navbar filter>
        <Navbar.Tab label="In Flight Orders" component={null} />,
        <Navbar.Tab label="Active Service" component={null} />,
        <Navbar.Tab label="Active Service 1" component={null} />
      </Navbar>
    );
    expect(wrapper).toMatchSnapshot();
  });

child.type().toLowerCase() !== 'tabs' is a bad way to do this check. Not every child element is React component, and not every class or functional React component is allowed to be called like a function. It's unsafe hack that will result in error for almost every child except Tab . type should be compared against Tab instead.

The component will also fail if value === null .

A safer and simpler way to write it is:

const Navbar = ({ children, filter }) => {
  const tabs = React.Children.toArray(children)
  .filter(child => child.type === Navbar.Tab)
  .map(child => child.props.component)
  .filter(Boolean);

  return (
    <>
      {tabs}
    </>
  )
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM