mardi 8 octobre 2019

How to get React children from Enzyme

I've implemented a "slot" system in React from this article: Vue Slots in React. However, I'm running into trouble when trying to test the component due to a "mismatch" between the Enzyme wrapper's children and React's children.

This is the function to get a "slot" child from React children. The function works as expected within a app component when provided with the children prop, but doesn't work during testing as the "children" isn't the same format as React.children.

const getSlot = (children, slot) => {
  if (!children) return null;

  if (!Array.isArray(children)) {
    return children.type === slot ? children : null;
  }

  // Find the applicable React component representing the target slot
  return children.find((child) => child.type === slot);
};

The TestComponent isn't directly used in the tests, but is intended to show an example of how the "slots" would be implemented in a component.

const TestComponent = ({ children }) => {
  const slot = getSlot(children, TestComponentSlot);

  return (
    <div id="parent">
      <div id="permanentContent">Permanent Content</div>
      {slot && <div id="optionalSlot">{slot}</div>}
    </div>
  );
};

const TestComponentSlot = () => null;
TestComponent.Slot = TestComponentSlot;

This is the basics of the tests I am trying to write. Essentially, creating a super basic component tree and then checking if the component's children contained the expected "slot" component. However, the getSlot function always returns null as the input isn't the same as the input provided by React children when used within the app.

it("Finds slots in React children", () => {
  const wrapper = mount(
    <div>
      <TestComponent.Slot>Test</TestComponent.Slot>
    </div>
  );

  // Unsure how to properly get the React children to test method.
  //   Below are some example that don't work...

  // Neither approach returns React children like function expects
  const children = wrapper.children();
  const { children } = wrapper.instance();

  // TODO: Eventually get something I can put into function
  const slot = getSlot(children, TestComponentSlot);
});

Any help or insights would be greatly appreciated!

Aucun commentaire:

Enregistrer un commentaire