Свойства для конкретных дочерних компонентов

#reactjs #react-proptypes

#reactjs #react-proptypes

Вопрос:

Я изо всех сил пытаюсь выяснить, как указать PropTypes для набора конкретных дочерних компонентов. Моему диалоговому компоненту разрешено получать компоненты типа Title, Body и / или Footer. Все эти компоненты могут использоваться только один раз, но могут появляться вместе в одно и то же время.

Есть ли рекомендуемый способ указать соответствующий propType?

 const Title = ({ text }) => (
  <h1>{ text }</h1>
);

const Body = ({ text }) => (
  <p>{ text }</p>
);

const Footer = ({ text }) => (
  <small>{ text }</small>
);

const Dialog = ({ children }) => (
  React.Children.map(children, (child) => {
    return (
      <div>{child}</div>
    )
  })
);

Dialog.propTypes = {
  children: PropTypes.oneOfType([
    PropTypes.instanceOf(Title),
    PropTypes.instanceOf(Body),
    PropTypes.instanceOf(Footer)
  ]).isRequired
}
  

Ответ №1:

Отредактировано

Вы могли бы использовать пользовательскую проверку propType, чтобы проверить, соответствует ли значение prop правилам, ожидаемым вашим компонентом: имя компонента (заголовок, тело и / или нижний колонтитул), если есть только один из каждого или нет, порядок этих компонентов…

Но это перебор.

На мой взгляд, лучше всего располагать эти компоненты внутри диалогового компонента и использовать props для его настройки. например:

CodeSandbox

 const Title = ({ children }) => <h2>{children}</h2>;

const Dialog = ({
  title,
  showConfirmationButton,
  showCancelButton,
  onConfirmation,
  onCancel,
  children
}) => (
  <div>
    {!!title amp;amp; <Title>{title}</Title>}
    {children}
    {(showConfirmationButton || showCancelButton) amp;amp; <hr />}
    {showCancelButton amp;amp; <button onClick={onCancel}>Cancel</button>}
    {showConfirmationButton amp;amp; <button onClick={onConfirmation}>Ok</button>}
  </div>
);

Dialog.propTypes = {
  title: PropTypes.string,
  showOkButton: PropTypes.bool,
  onClickOk: PropTypes.func,
  children: PropTypes.any.isRequired
};

export default function App() {
  return (
    <Dialog
      title="Title dialog"
      showConfirmationButton
      onConfirmation={() => console.log("ok")}
      showCancelButton
      onCancel={() => console.log("cancel")}
    >
      <p>The Dialog body as children.</p>
    </Dialog>
  );
}
  

Или, если вам все еще нужно передать компонент в качестве prop, тогда лучшим должно быть:

 const Dialog = ({ title, body, footer }) => (
    <div>
        { title } 
        { body }
        { footer }
    </div>
)

Dialog.propTypes = {
    title: PropTypes.instanceOf(Title),
    footer: PropTypes.instanceOf(Footer),
    body: PropTypes.instanceOf(Body)
}

  

Вы можете проверить доступные типы реквизитов здесьhttps://reactjs.org/docs/typechecking-with-proptypes.html

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

1. Проблема с первым решением, которое вы предоставили, заключается в том, что оно принимает любой элемент в реквизитах и явно не требует передачи элементов Title , Body и Footer — следовательно, это не то, что просил OP, и я искал.