В реальных React-приложениях компонентов значительно больше. Часть из них — самостоятельные, часть используется только в составе других.
Один из способов компоновки компонентов вам уже известен — children
. Причём нет никакой разницы, являются ли потомки встроенными в React компонентами или это отдельно написанные компоненты.
class Alert extends React.Component {
render() {
const { children } = this.props;
return (
<div className="alert alert-primary">
{children}
</div>
);
}
}
const vdom = (
<Alert>
<p>Paragraph 1</p>
<hr />
<p className="mb-0">Paragraph 2</p>
</Alert>
);
const root = ReactDOM.createRoot(document.getElementById('react-root'));
root.render(vdom);
В некоторых ситуациях внутрь компонента нужно передавать только определённые, специально созданные под него компоненты. Например, компонент Card
до текущего момента был реализован так, что он на вход мог принимать только пропсы:
class Card extends React.Component {
render() {
const { title, text } = this.props;
return (
<div className="card">
<div className="card-body">
<h4 className="card-title">{title}</h4>
<p className="card-text">{text}</p>
<button type="button" className="btn btn-primary">Go somewhere</button>
</div>
</div>
);
}
}
В реальности это решение так себе. Кастомизация отсутствует полностью, можно передать только то, что изначально задумано, и то в формате строк. Ни о каком сложном содержимом не может быть и речи. Правильный подход выглядел бы так:
<Card>
<CardImgTop src="path/to/image" />
<CardBody>
<CardTitle>Body</CardTitle>
</CardBody>
</Card>
Такой подход позволяет заменять компоненты внутри Card
на любые другие.
В тех ситуациях, когда композиция не требуется, можно просто брать и использовать любые сторонние компоненты внутри своих.
See the Pen js_react_nested_components by Hexlet (@hexlet) on CodePen.
Вкладывать можно сколько угодно раз и какие угодно компоненты. Но здесь кроется одна опасность. Желание построить идеальную архитектуру толкает разработчиков заранее планировать то, как разбить приложение на компоненты и сразу их реализовать. Важно понимать, что вложенность сама по себе — это усложнение понимания, так как придётся постоянно прыгать из одного компонента в другой. Кроме того, жёсткая структура свяжет вас по рукам и ногам, рефакторинг просто так не сделаешь, и желание его делать сильно поубавится из-за любви к своему решению. Будьте прагматичны. Оптимальный путь добавлять новые компоненты — это следить за моментом, когда вам становится сложно в текущем компоненте из-за объёмов и количества переменных, с которыми приходится иметь дело одномоментно. И даже в этом случае часто достаточно выделить дополнительные функции рендеринга внутри самого компонента, например так: renderItem
.
Состояние
Один из самых частых вопросов у тех, кто только начинает знакомиться с React, связан с тем, как распределять состояние по компонентам. Короткий ответ: никак. Почти во всех ситуациях разделение состояния усложнит код и работу с ним. Правильный подход — создать корневой компонент, который содержит всё состояние внутри себя, а все нижележащие компоненты получают свои данные как пропсы. Само состояние должно быть максимально плоским, как реляционная база данных. Тогда можно спокойно применять нормализацию и безболезненно выполнять обновления.
Иногда могут возникать ситуации, когда необходимые в глубине свойства приходится протаскивать сквозь множество промежуточных компонентов, которые сами эти пропсы не используют. Это еще одна причина стараться не увлекаться глубокой вложенностью. С другой стороны, в следующем курсе вы познакомитесь с Redux, который во многом решает эту проблему (и много других).
Колбеки
Из сказанного выше возникает еще одна сложность: что, если событие возникает в глубинном компоненте, у которого нет своего состояния? Без использования Redux, по сути, только один выход. Корневой компонент должен пробрасывать колбеки во внутренние компоненты, а те, в свою очередь, пробрасывают их дальше по необходимости.
Остались вопросы? Задайте их в разделе «Обсуждение»
Вам ответят команда поддержки Хекслета или другие студенты
Для полного доступа к курсу нужен базовый план
Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.