Узнайте, как эффективно структурировать и организовывать компоненты React.
React — это популярная библиотека JavaScript для создания пользовательских интерфейсов. Одной из ключевых особенностей React является его компонентная архитектура, которая позволяет разработчикам создавать многократно используемые и компонуемые элементы пользовательского интерфейса. Композиция компонентов — это процесс объединения небольших независимых компонентов для создания более крупных и сложных компонентов. В этой статье мы рассмотрим пять лучших практик для композиции компонентов React и предоставим примеры кода, иллюстрирующие каждый из них.
1. Принцип единой ответственности
Принцип единой ответственности (SRP) — это фундаментальный принцип разработки программного обеспечения, который гласит, что компонент должен нести единую ответственность. В контексте состава компонентов React это означает, что каждый компонент должен отвечать за определенную функциональность или функцию.
Придерживаясь SRP, мы гарантируем, что наши компоненты сфокусированы и просты для понимания. Это делает их более пригодными для повторного использования и обслуживания, поскольку мы можем легко идентифицировать и модифицировать компонент, не затрагивая другие части нашего приложения.
Давайте рассмотрим пример, где у нас есть компонент «UserCard», который отображает информацию о пользователе. Вместо включения дополнительных функций, таких как редактирование или удаление пользователя, в компонент «UserCard», мы можем создать отдельные компоненты для этих действий. Такое разделение задач позволяет нам повторно использовать компонент «UserCard» в разных контекстах, не беспокоясь о его внутренней реализации.
Вот пример того, как мы можем применить SRP в составе компонентов React:
// UserCard component responsible for displaying user information
const UserCard = ({ user }) => {
return (
<div>
<h2>{user.name}</h2>
<p>{user.email}</p>
{/* Additional user information */}
</div>
);
};
// EditUserButton component responsible for editing a user
const EditUserButton = ({ onClick }) => {
return <button onClick={onClick}>Edit User</button>;
};
// DeleteUserButton component responsible for deleting a user
const DeleteUserButton = ({ onClick }) => {
return <button onClick={onClick}>Delete User</button>;
};
Разделив обязанности на разные компоненты, мы можем легко повторно использовать компонент «UserCard» в различных контекстах, сохраняя при этом чистую и сфокусированную кодовую базу.
2. Компонентная композиция на основе реквизита
Состав компонентов на основе реквизита — это распространенный подход в React, когда компоненты получают данные и поведение через реквизит. Это позволяет легко создавать компоненты, передавая различные реквизиты для достижения различной функциональности или внешнего вида.
Используя композицию на основе реквизита, мы можем создавать гибкие и многократно используемые компоненты, которые можно адаптировать к различным вариантам использования. Предоставляя реквизиты в качестве входных данных для компонентов, мы позволяем их настраивать и настраивать без изменения их внутренней реализации.
Давайте посмотрим на пример, где мы создаем компонент «Кнопка» с разными реквизитами:
const Button = ({ text, onClick }) => {
return <button onClick={onClick}>{text}</button>;
};
// Composing the Button component with different props
const App = () => {
return (
<div>
<Button text="Click me" onClick={() => console.log("Button clicked")} />
<Button text="Submit" onClick={() => console.log("Submit clicked")} />
<Button text="Cancel" onClick={() => console.log("Cancel clicked")} />
</div>
);
};
В этом примере компонент «Кнопка» скомпонован несколько раз с разными реквизитами, что приводит к кнопкам с другим текстом и обработчиками кликов. Это демонстрирует, как композиция на основе реквизита позволяет нам повторно использовать один и тот же компонент с различными конфигурациями.
3. Составные компоненты
Составные компоненты — это шаблон в React, в котором набор компонентов работает вместе для достижения определенной функциональности. Эти компоненты предназначены для совместного использования и взаимодействия друг с другом через общее состояние или контекст.
Шаблон составного компонента обеспечивает более высокий уровень абстракции, позволяя разработчикам создавать сложные функции, сохраняя при этом простой и интуитивно понятный API для потребителей.
Чтобы реализовать составные компоненты, мы можем использовать контекст React для обмена состоянием или другими необходимыми данными между компонентами. Это позволяет компонентам координировать свои действия и без проблем работать вместе.
Давайте рассмотрим пример компонента Tabs, где у нас есть компонент TabsList для отображения списка вкладок и компонент TabPanel для отображения содержимого выбранной вкладки:
const TabsContext = React.createContext();
const Tabs = ({ children }) => {
const [activeTab, setActiveTab] = React.useState(0);
const handleTabClick = (index) => {
setActiveTab(index);
};
return (
<TabsContext.Provider value={{ activeTab, onTabClick: handleTabClick }}>
{children}
</TabsContext.Provider>
);
};
const TabsList = ({ children }) => {
const { activeTab, onTabClick } = React.useContext(TabsContext);
return (
<div>
{React.Children.map(children, (child, index) =>
React.cloneElement(child, {
isActive: index === activeTab,
onClick: () => onTabClick(index),
}),
)}
</div>
);
};
const Tab = ({ children, isActive, onClick }) => {
return (
<button
onClick={onClick}
style={{ fontWeight: isActive ? 'bold' : 'normal' }}
>
{children}
</button>
);
};
const TabPanel = ({ children }) => {
const { activeTab } = React.useContext(TabsContext);
return <div>{children[activeTab]}</div>;
};
const App = () => {
return (
<Tabs>
<TabsList>
<Tab>Tab 1</Tab>
<Tab>Tab 2</Tab>
<Tab>Tab 3</Tab>
</TabsList>
<TabPanel>
<div>Content for Tab 1</div>
<div>Content for Tab 2</div>
<div>Content for Tab 3</div>
</TabPanel>
</Tabs>
);
};
export default App;
В этом примере компонент Tabs предоставляет состояние activeTab и функцию onTabClick через TabsContext.Provider. Компонент TabsList и компонент Tab используют состояние activeTab и функцию onTabClick из контекста для обработки выбора и рендеринга вкладок.
Используя составные компоненты, мы можем создать компонент вкладок, который инкапсулирует логику и управление состоянием, позволяя потребителям легко создавать и настраивать функциональные возможности вкладок.
4. Рендер реквизит
Render Props — это еще один метод композиции компонентов в React. Он включает в себя передачу функции в качестве реквизита компоненту, что позволяет компоненту отображать свой вывод с использованием предоставленной функции.
Используя шаблон Render Props, компоненты могут предоставлять гибкий и компонуемый API, который позволяет потребителям управлять поведением рендеринга. Это обеспечивает мощные возможности настройки и расширения.
Давайте рассмотрим пример, в котором у нас есть компонент Toggle, который предоставляет состояние переключения и функцию переключения своим дочерним элементам, используя шаблон Render Props:
const Toggle = ({ children }) => {
const [on, setOn] = React.useState(false);
const toggle = () => {
setOn((prevOn) => !prevOn);
};
return children({ on, toggle });
};
const App = () => {
return (
<Toggle>
{({ on, toggle }) => (
<div>
<button onClick={toggle}>{on ? 'ON' : 'OFF'}</button>
{on && <p>The toggle is ON</p>}
</div>
)}
</Toggle>
);
};
В этом примере компонент Toggle показывает свое состояние (включено) и поведение (переключение) через дочернюю функцию. Потребители могут предоставить свою собственную логику рендеринга, используя предоставленное состояние и функцию.
Шаблон Render Props обеспечивает динамическую и гибкую композицию, поскольку потребители имеют полный контроль над визуализацией вывода компонента.
5. Компоненты высшего порядка (HOC)
Компоненты высшего порядка (HOC) — это шаблон в React, где функция берет компонент и возвращает новый компонент с расширенными функциями.
HOC позволяют повторно использовать логику компонентов и добавлять к компонентам дополнительные возможности без изменения их исходной реализации. Они позволяют решать сквозные проблемы и повторно использовать код, оборачивая компоненты функциями более высокого порядка.
Чтобы создать HOC, мы определяем функцию, которая принимает компонент в качестве аргумента и возвращает новый компонент с дополнительными функциями. HOC может модифицировать props, обернуть компонент дополнительными элементами или предоставить данные через контекст.
Давайте посмотрим на пример HOC, который добавляет индикатор загрузки к компоненту:
const withLoadingIndicator = (Component) => {
return function WithLoadingIndicator({ isLoading, ...props }) {
if (isLoading) {
return <div>Loading...</div>;
}
return <Component {...props} />;
};
};
const MyComponent = ({ data }) => {
return <div>{data}</div>;
};
const MyComponentWithLoadingIndicator = withLoadingIndicator(MyComponent);
const App = () => {
const isLoading = true;
const data = 'Hello, world!';
return (
<div>
<MyComponentWithLoadingIndicator isLoading={isLoading} data={data} />
</div>
);
};
В этом примере withLoadingIndicator HOC принимает компонент и возвращает новый компонент (WithLoadingIndicator), который отображает индикатор загрузки, если свойство isLoading истинно. В противном случае он отображает исходный компонент.
Используя HOC, мы можем улучшать компоненты с многократно используемыми и сквозными функциями, такими как аутентификация, выборка данных или обработка ошибок, без изменения исходных компонентов. Это способствует повторному использованию кода и разделению задач.
Заключение
В этой статье мы рассмотрели пять лучших практик для композиции компонентов React. Следуя этим практикам, мы можем создавать более повторно используемые, поддерживаемые и гибкие компоненты в наших приложениях React.
- Принцип единой ответственности: разрабатывайте компоненты с единой ответственностью, чтобы улучшить возможность повторного использования и удобство сопровождения.
- Состав компонентов на основе реквизита: создавайте компоненты, передавая различные реквизиты для достижения различной функциональности или внешнего вида.
- Составные компоненты: разрабатывайте компоненты, которые работают вместе и взаимодействуют через общее состояние или контекст, чтобы обеспечить более высокий уровень абстракции и гибкости.
- Render Props: используйте шаблон Render Props, чтобы предоставить функцию в качестве реквизита, позволяя потребителям управлять поведением рендеринга компонента.
- Компоненты высшего порядка (HOC): создавайте HOC для обертывания компонентов и добавления дополнительных возможностей или сквозных задач без изменения их исходной реализации.
Применяя эти лучшие практики, мы можем создавать компонуемые и расширяемые компоненты, которые способствуют повторному использованию кода, разделению задач и более гибкой архитектуре в наших приложениях React.
Помните, что композиция компонентов — это мощная концепция, которая позволяет нам создавать сложные пользовательские интерфейсы из более мелких строительных блоков многократного использования. Это позволяет нам создавать масштабируемые и удобные в сопровождении приложения, способствуя повторному использованию кода, модульности и гибкости.
Дополнительные материалы на PlainEnglish.io.
Подпишитесь на нашу бесплатную еженедельную рассылку новостей. Подпишитесь на нас в Twitter, LinkedIn, YouTube и Discord .