Is it an anti-pattern to use the props of your child components to render another component?

Viewed 211

I have a component in React that can take an indefinite number of children, and it uses those children to generate another component, with the original children composed within it. The point is to wrap the original child component with a new component that decorates the functionality of it. The code looks like this:

const Form = ({ children }) => (
  <FormGroupComponent>
    {children.map(child => (
    <CheckboxAndChild
      checked={child.props.checked}
      setCheckbox={child.props.setCheckbox}
    >
      {child}
    </CheckboxAndPicker>
  ))}
  </FormGroupComponent>
);

const CheckboxAndPicker = ({ checked, setCheckbox, children }) => (
  <div>
    <div>
      <Checkbox
        checked={checked}
        onChange={() => setCheckbox(!checked)}
      />
    </div>
    <div>{checked && children}</div>
    <div/>
  </div>
);

These two functional components can be used like this:

...
        <Form>
          <TimePicker
            {...timePickerProps}
            checked={showTimeOne}
            setChecked={setTimeOne}
          />
          <TimePicker
            {...timePickerProps}
            checked={showTimeTwo}
            setChecked={setTimeTwo}
          />
        </Form>
...

I find two things strange about this code:

  1. The "TimePicker" component doesn't normally have a "checked" and "setChecked" prop within it, and doesn't do anything with those props itself. Those props are only used to render the "CheckboxAndPicker" component within the "Form" component.
  2. The "Form" component accesses its children component's props in order to generate a new component using those props.

Is this an anti-pattern, or is this sort of functionality acceptable when decorating existing components with new props, and using those new props to generate new components?

1 Answers

I decided to remove the Form component, and directly use the FormGroupComponent component. By doing this I removed the need to use the props of its children props, making the code more readable (though a little more verbose). The following is the change I made:

        <FormGroupComponent>
          <CheckboxAndPicker
            checked={showTimeOne}
            setCheckbox={setTimeOne}
          >
            <TimePicker
              {...timePickerStyle}
            />
          </CheckboxAndPicker>
          <CheckboxAndPicker
            checked={showTimeTwo}
            setChecked={setTimeTwo}
          >
            <TimePicker
              {...timePickerStyle}
            />
          </CheckboxAndPicker>
        </FormGroupComponent>

I think this is an improvement over the code in the original post because:

  1. We have removed the need for a Form component.
  2. We've removed the need of mapping through the children of our Form component and getting the props of the Form component's children while still within the Form component.
  3. We are no longer attaching new props to the TimePicker component that are unused by the actual TimePicker component.

Factoring out the usage of the prop's children has made this code much more straightforward in my opinion. Therefore I think that it probably was an anti-pattern to call the props of our child components within the parent component, as it needlessly complicated the code.

Related