Узнайте, как эффективно структурировать и организовывать компоненты 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 .