✈️ Патерни проектування в React (2025) 📈

pic

Вступ

У React використання дизайнерських патернів може призвести до більш масштабованих, підтримуваних та ефективних застосунків. Ця стаття досліджує деякі основні патерни проектування в React, такі як патерн контейнерних і презентаційних компонентів, патерн вищого порядку (Higher-Order Component, HOC), патерн Render Props та патерн кастомних хуків. Кожен патерн буде проілюстровано за допомогою сучасних хуків React.

1. Патерн контейнерних та презентаційних компонентів

pic

Концепція: Цей патерн розділяє компоненти на дві категорії: контейнерні компоненти (розумні компоненти), які обробляють стан та логіку, та презентаційні компоненти (тупі компоненти), які відповідають за відображення інтерфейсу.

Переваги:

  • Розподіл відповідальності: Зберігає бізнес-логіку окремо від рендерингу UI.
  • Повторне використання: Презентаційні компоненти можна використовувати в різних частинах застосунку.

Реалізація:

Контейнерний компонент:

 // TodoContainer.js  
import React, { useState, useEffect } from 'react';  
import TodoList from './TodoList';  

const TodoContainer = () => {  
 const [todos, setTodos] = useState([]);  
 useEffect(() => {  
 fetch('/api/todos')  
 .then(response => response.json())  
 .then(data => setTodos(data));  
 }, []);  
 return ;  
};  
export default TodoContainer;

Презентаційний компонент:

 // TodoList.js  
import React from 'react';  

const TodoList = ({ todos }) => (  

    {todos.map(todo => (    
{todo.text}
    ))}    
   );   
export default TodoList;  

2. Патерн вищого порядку (Higher-Order Component, HOC)

Концепція: Компонент вищого порядку (HOC) — це функція, яка приймає компонент і повертає новий компонент з додатковими пропсами або поведінкою.

pic

Переваги:

  • Повторне використання коду: Інкапсулює загальну поведінку, яку можна використовувати в кількох компонентах.
  • Розширення: Дозволяє розширювати компоненти додатковою функціональністю.

Реалізація:

 // withLogging.js  
import React, { useEffect } from 'react';  

const withLogging = WrappedComponent => {  
 return props => {  
 useEffect(() => {  
 console.log('Component mounted');  
 }, []);  
 return ;  
 };  
};  
export default withLogging;
 // MyComponent.js  
import React from 'react';  
import withLogging from './withLogging';  

const MyComponent = () =>  
 Hello, World!
 ;  
export default withLogging(MyComponent);

3. Патерн Render Props

Концепція: Цей патерн передбачає використання пропсу, який є функцією, для спільного використання коду між компонентами.

pic

Переваги:

  • Гнучкість: Забезпечує спосіб передачі динамічної поведінки компонентам.
  • Повторне використання коду: Сприяє повторному використанню коду, передаючи функції як пропси.

Реалізація:

 // MouseTracker.js  
import React, { useState } from 'react';  

const MouseTracker = ({ render }) => {  
 const [position, setPosition] = useState({ x: 0, y: 0 });  
 const handleMouseMove = event => {  
 setPosition({  
 x: event.clientX,  
 y: event.clientY  
 });  
 };  
 return (  
    {render(position)}  
 );  
};  
export default MouseTracker;
 // App.js  
import React from 'react';  
import MouseTracker from './MouseTracker';  

const App = () => (  
     (  
The mouse position is ({x}, {y})
    )} />  
);  
export default App;

## Патерн кастомних хуків

**Концепція**: Кастомні хуки дозволяють інкапсулювати логіку та управління станом у повторно використовувані функції.

![pic](https://drive.javascript.org.ua/4ae8c65cc31_JMV_gCRt1Z7uyelAzZxgaA_png)

**Переваги**:

- **Повторне використання коду**: Витягує і повторно використовує логіку в різних компонентах.
- **Спрощення**: Спрощує логіку компонентів, переміщуючи складну логіку в хуки.

**Реалізація**:

// useFetchData.js
import { useState, useEffect } from 'react';

const useFetchData = url => {
const [data, setData] = useState(null);
useEffect(() => {
fetch(url)
.then(response => response.json())
.then(data => setData(data));
}, [url]);
return data;
};
export default useFetchData;
```

 // DataDisplay.js  
import React from 'react';  
import useFetchData from './useFetchData';  

const DataDisplay = ({ url }) => {  
 const data = useFetchData(url);  
 return data ? 
{JSON.stringify(data, null, 2)}
 : 
Loading...
;  
};  
export default DataDisplay;

5. Патерн комбінованих компонентів

Концепція: Патерн комбінованих компонентів дозволяє комбінувати компоненти разом, щоб сформувати єдину цілісну одиницю, де кожен компонент вносить свій вклад у досягнення більшої мети.

pic

Переваги:

  • Інкапсуляція: Компоненти працюють разом безшовно, при цьому кожен з них зберігає свою відповідальність.
  • Гнучкість: Користувачі можуть налаштовувати поведінку і вигляд комбінованого компонента через його частини.

Реалізація:

 // Toggle.js  
import React, { useState } from 'react';  

const Toggle = ({ children }) => {  
 const [on, setOn] = useState(false);  
 const toggle = () => {  
 setOn(!on);  
 };  
 const getChildProps = () => {  
 return {  
 on,  
 toggle,  
 };  
 };  
 return <>{React.Children.map(children, child => React.cloneElement(child, getChildProps()))};  
};  
export default Toggle;
 // ToggleButton.js  
import React from 'react';  

const ToggleButton = ({ on, toggle }) => (  
    {on ? 'Turn Off' : 'Turn On'}  
);  
export default ToggleButton;
 // ToggleMessage.js  
import React from 'react';  

const ToggleMessage = ({ on }) => (  
    {on ? 'The button is ON' : 'The button is OFF'}  
);  
export default ToggleMessage;
 // App.js  
import React from 'react';  
import Toggle from './Toggle';  
import ToggleButton from './ToggleButton';  
import ToggleMessage from './ToggleMessage';  

const App = () => (  
     );  
export default App;
  • Компонент Toggle: Керує станом (on або off) та надає функцію toggle своїм дітям через патерн комбінованих компонентів.
  • Компонент ToggleButton: Отримує стан on і функцію toggle як пропси для обробки подій кліку та відображення відповідного тексту.
  • Компонент ToggleMessage: Отримує стан on для відображення повідомлення в залежності від поточного стану.

Цей патерн дозволяє компонентам ToggleButton і ToggleMessage працювати разом безшовно під керівництвом компонента Toggle, демонструючи інкапсуляцію і гнучкість патерну комбінованих компонентів.

Висновок

Розуміння та впровадження патернів проектування в React з хуками може значно підвищити масштабованість, підтримуваність і ефективність ваших застосунків. Використовуючи патерни, такі як контейнерні та презентаційні компоненти, компоненти вищого порядку (Higher-Order Components, HOC), Render Props, комбіновані компоненти та кастомні хуки, ви можете створювати модульний і повторно використовуваний код, який відповідає кращим практикам. Експериментуйте з цими патернами, щоб побачити, як вони можуть покращити ваші React проекти.

Перекладено з: ✈️ Design Patterns in React (2025) 📈

Leave a Reply

Your email address will not be published. Required fields are marked *