Является ли антишаблоном использование реквизитов ваших дочерних компонентов для рендеринга другого компонента?

#javascript #reactjs

#javascript #reactjs

Вопрос:

У меня есть компонент в React, который может принимать неопределенное количество дочерних элементов, и он использует эти дочерние элементы для создания другого компонента, в состав которого входят исходные дочерние элементы. Суть в том, чтобы обернуть исходный дочерний компонент новым компонентом, который дополняет его функциональность. Код выглядит следующим образом:

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

Эти два функциональных компонента можно использовать следующим образом:

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

Я нахожу две вещи странными в этом коде:

  1. Компонент «TimePicker» обычно не имеет в себе реквизитов «checked» и «setChecked» и ничего не делает с самими этими реквизитами. Эти реквизиты используются только для рендеринга компонента «CheckboxAndPicker» в компоненте «Form».
  2. Компонент «Форма» обращается к реквизитам своего дочернего компонента, чтобы сгенерировать новый компонент с использованием этих реквизитов.

Является ли это антишаблоном или такая функциональность приемлема при украшении существующих компонентов новыми реквизитами и использовании этих новых реквизитов для создания новых компонентов?

Комментарии:

1. «Неопределенное количество дочерних элементов», вероятно, более точно, чем «бесконечные дочерние элементы».

2. Да, это определенно кажется плохим способом решения проблем. Я бы сказал, что либо Form компонент, либо CheckboxAndPicker компонент (или оба) должны отслеживать, какие дочерние элементы отмечены / сняты. TimePicker не нужно знать, проверено это или нет, если это внешнее по отношению к TimePicker , и не выглядит хорошо, когда один компонент подключается к другому с целью вызова его установщиков.

Ответ №1:

Я решил удалить компонент Form и напрямую использовать компонент FormGroupComponent . Сделав это, я устранил необходимость использования реквизитов его дочерних реквизитов, сделав код более читаемым (хотя и немного более подробным). Ниже приведены изменения, которые я внес:

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

Я думаю, что это улучшение по сравнению с кодом в исходном сообщении, потому что:

  1. Мы устранили необходимость в компоненте формы.
  2. Мы устранили необходимость сопоставления через дочерние элементы нашего компонента формы и получения реквизитов дочерних элементов компонента формы, все еще находясь внутри компонента формы.
  3. Мы больше не прикрепляем к компоненту TimePicker новые реквизиты, которые не используются фактическим компонентом TimePicker.

На мой взгляд, учет использования дочерних элементов prop сделал этот код намного более простым. Поэтому я думаю, что, вероятно, было антишаблоном вызывать реквизиты наших дочерних компонентов внутри родительского компонента, поскольку это излишне усложняло код.