#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 для его настройки. например:
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, и я искал.