1. Що таке React?
- React — це JavaScript-бібліотека для створення користувацьких інтерфейсів. Основні характеристики:
-
Компонентний підхід: UI розбивається на окремі компоненти, які можна повторно використовувати.
-
Virtual DOM: Забезпечує ефективне оновлення інтерфейсу, мінімізуючи маніпуляції з реальним DOM.
-
Декларативність: Ви описуєте, як має виглядати UI в певному стані, а React забезпечує його відповідність.
-
Однонаправлений потік даних: Дані передаються згори донизу через props, що спрощує контроль за станом.
- React створений Facebook і широко використовується для розробки SPA (Single Page Applications).
2. Перерахуйте особливості React?
-
Компонентний підхід: Код розділений на багаторазові, незалежні компоненти.
-
Віртуальний DOM: Швидке оновлення інтерфейсу без прямого маніпулювання DOM.
-
Односпрямований потік даних: Дані передаються з батьківських компонентів у дочірні через пропси.
-
JSX: Розширення синтаксису JavaScript для написання UI у вигляді XML-подібного коду.
-
Стан і життєвий цикл: Компоненти можуть зберігати і управляти своїм станом.
-
React Hooks: Додають можливості роботи зі станом і побічними ефектами у функціональних компонентах.
-
Екосистема: Підтримує бібліотеки на кшталт React Router, Redux для розширення функціоналу.
-
SEO-френдлі (з Next.js): Серверний рендеринг для кращої індексації.
-
Мобільна розробка: React Native дозволяє створювати мобільні додатки на основі React.
-
Відкритий код: Активна підтримка спільноти.
3. Що таке Virtual DOM в React?
- Virtual DOM — це віртуальне представлення реального DOM, яке React використовує для ефективного оновлення інтерфейсу.
-
Рендеринг у Virtual DOM: При зміні стану або пропсів компонентів React оновлює Virtual DOM.
-
Diffing: React порівнює новий Virtual DOM зі старою версією, визначаючи мінімальний набір змін.
-
Оновлення реального DOM: Виявлені зміни застосовуються до реального DOM, зводячи до мінімуму кількість маніпуляцій.
-
Оптимізація оновлень DOM, що значно покращує продуктивність додатків.
-
Coming Soon... 😎
4. Навіщо потрібен атрибут key при рендері списків?
- Атрибут
key
використовується для ідентифікації елементів у списках під час рендеру.
-
Оптимізація оновлень: React використовує
key
для ефективного оновлення інтерфейсу, швидко визначаючи, які елементи змінити, додати або видалити. -
Запобігання зайвим рендерам:
key
допомагає уникнути перерендеру незмінених елементів. -
Збереження стану компонентів: Наприклад, якщо елемент списку містить форму,
key
дозволяє React зберігати її стан між оновленнями.
-
Значення
key
має бути унікальним серед братніх елементів. -
Найкраще підходять стабільні ідентифікатори (наприклад,
id
з бази даних). -
Не рекомендується використовувати індекс масиву як
key
, оскільки це може призвести до помилок при зміні порядку елементів.
const items = ["Apple", "Banana", "Cherry"];
return (
<ul>
{items.map((item, index) => (
<li key={item}>{item}</li> // Унікальний key для кожного елемента
))}
</ul>
);
5. Що таке JSX?
- JSX (JavaScript XML) — це синтаксис, який дозволяє писати структури UI у вигляді XML-подібного коду всередині JavaScript. JSX є розширенням JavaScript і використовується в React для опису, як виглядає інтерфейс.
- XML-подібний синтаксис: Нагадує HTML, але використовується у JavaScript.
const element = <h1>Hello, world!</h1>;
- Вбудований JavaScript: Ви можете писати JavaScript-код у фігурних дужках
{}
.
const name = "Alice";
const element = <h1>Hello, {name}!</h1>;
- Трансляція: JSX компілюється в звичайний JavaScript, використовуючи такі бібліотеки, як Babel.
const element = <h1>Hello</h1>;
// Перетворюється в:
const element = React.createElement("h1", null, "Hello");
- Атрибути: Використовуються як у HTML, але замість
class
пишетьсяclassName
, а замістьfor
—htmlFor
.
const input = <input type="text" className="input-field" />;
- JSX повертає дерево елементів: JSX-вираз може повертати лише один кореневий елемент. Використовуйте
<React.Fragment>
або порожній тег<>
для групування.
return (
<>
<h1>Title</h1>
<p>Description</p>
</>
);
- Зручне створення UI-компонентів.
- Зрозумілий і читабельний синтаксис.
- Тісна інтеграція з JavaScript-логікою.
JSX не обов'язковий у React, але широко використовується через зручність і гнучкість.
6. Різниця між станом (state) та пропсами (props)?
Критерій | State | Props |
---|---|---|
Призначення | Зберігає внутрішній стан компонента. | Передає дані від батьківського компонента до дочірнього. |
Змінюваність | Може змінюватися всередині компонента. | Незмінні (read-only). |
Доступність | Доступний тільки в компоненті, де визначений. | Доступний у дочірньому компоненті через атрибути. |
Ініціалізація | Встановлюється в компоненті за допомогою useState або конструктора. |
Визначається батьківським компонентом. |
Область використання | Для збереження динамічних даних, що можуть змінюватися. | Для передачі фіксованих або динамічних даних. |
Хто керує? | Компонент, у якому state визначений. | Батьківський компонент. |
7. Що таке React Хуки (Hooks)?
- React Хуки (Hooks) — це функції, які дозволяють вам використовувати стан та інші можливості React без написання класів.
- useState — дозволяє додавати стан в функціональні компоненти.
const [state, setState] = useState(initialState);
- useEffect — дозволяє виконувати побічні ефекти (наприклад, запити до API або підписки) у функціональних компонентах.
useEffect(() => {
// код для ефекту
}, [dependencies]); // залежності
- useContext — доступ до значень контексту без необхідності використовувати компонент Consumer.
const value = useContext(MyContext);
- useRef — дозволяє створювати посилання на DOM-елементи або зберігати значення між рендерами без змін стану.
const myRef = useRef(initialValue);
- useReducer — альтернатива useState, зручна для управління складнішими станами через редуктори, подібно до Redux.
const [state, dispatch] = useReducer(reducer, initialState);
- useMemo — оптимізує обчислення значень, щоб уникнути непотрібних повторних обчислень.
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
- useCallback — повертає мемоізовану версію функції, щоб вона не створювалась знову при кожному рендері.
const memoizedCallback = useCallback(() => {
// функція;
}, [dependencies]);
-
Функціональні компоненти: Замість класових компонентів ви можете використовувати функціональні компоненти з хуками.
-
Покращена читабельність: Логіка можна розділити на декілька хуків, що зменшує кількість коду та підвищує модульність.
-
Перерозподіл логіки: Хуки дозволяють повторно використовувати логіку в різних компонентах без створення складних ієрархій.
8. Що таке контекст (Context)?
- Контекст (Context) в React — це механізм для передачі даних через дерево компонентів без необхідності передавати ці дані через пропси на кожному рівні.
- React.createContext() — використовується для створення контексту.
const MyContext = React.createContext(defaultValue);
- Provider — компонент, який надає значення контексту. Він обгортає частину дерева компонентів і передає значення вниз через value.
<MyContext.Provider value={}>
<YourComponent />
</MyContext.Provider>
- Consumer — компонент, який споживає значення контексту. Зазвичай використовує функцію як дочірній елемент, що отримує значення контексту.
<MyContext.Consumer>
{value => }
</MyContext.Consumer>
- useContext — хук, який дозволяє доступити значення контексту без необхідності використовувати Consumer.
const value = useContext(MyContext);
-
Коли є потреба передавати дані між компонентами на різних рівнях ієрархії (наприклад, тема, мова або користувач).
-
Коли вам не хочеться передавати пропси через кілька рівнів компонентів, що може ускладнити код.
// Створення контексту
const ThemeContext = React.createContext("light");
// Компонент, який надає значення контексту
function App() {
return (
<ThemeContext.Provider value="dark">
<ThemedComponent />
</ThemeContext.Provider>
);
}
// Компонент, який споживає значення контексту
function ThemedComponent() {
const theme = useContext(ThemeContext);
return <div>The current theme is {theme}</div>;
}
-
Зручність в передачі глобальних значень.
-
Покращує масштабованість програми, зменшуючи кількість переданих пропсів.
9. Що таке портал (Portal)?
- Портал (Portal) у React — це спосіб рендерити дочірні елементи в DOM-вузол, який знаходиться за межами DOM-ієрархії батьківського компонента.
- React забезпечує портали через метод
ReactDOM.createPortal
, який приймає два аргументи:
-
React-елемент, що потрібно рендерити.
-
Цільовий DOM-вузол, у який слід вставити елемент.
ReactDOM.createPortal(child, container);
-
child — React-елемент, який потрібно рендерити.
-
container — DOM-вузол, де елемент буде вставлено.
import React from "react";
import ReactDOM from "react-dom";
function Modal({ children }) {
return ReactDOM.createPortal(
<div className="modal">{children}</div>,
document.getElementById("modal-root") // Цільовий вузол
);
}
function App() {
return (
<div>
<h1>Основний контент</h1>
<Modal>
<p>Це контент модального вікна</p>
</Modal>
</div>
);
}
-
Модальні вікна.
-
Спливаючі підказки (tooltips).
-
Контекстні меню.
- Ієрархія подій:
- Хоча елемент рендериться поза ієрархією DOM, обробка подій відбувається відповідно до React-ієрархії компонентів. Наприклад, події onClick підніматимуться до батьківських компонентів React.
- Гнучкість: Портали дозволяють вставляти елементи в місця, які не вписуються в поточну структуру DOM.
- Легке управління "плаваючими" елементами.
- Збереження контексту React навіть за межами основної DOM-ієрархії.
10. Методи життєвого циклу компонента у React?
- Методи життєвого циклу компонента в React використовуються для управління різними етапами життя компонентів: створення, оновлення та видалення.
- Монтування (Mounting): Коли компонент додається в DOM.
-
constructor(): Ініціалізація стану та прив'язка методів.
-
static getDerivedStateFromProps(props, state): Оновлення стану перед рендером (рідко використовується).
-
render(): Рендерить JSX у віртуальний DOM.
-
componentDidMount(): Викликається одразу після додавання компонента в DOM. Використовується для запитів API, ініціалізації бібліотек.
- Оновлення (Updating): Коли змінюються пропси або стан.
-
static getDerivedStateFromProps(props, state): Викликається перед кожним рендером.
-
shouldComponentUpdate(nextProps, nextState): Контролює, чи потрібно повторно рендерити компонент. За замовчуванням повертає true.
-
render(): Виконується для оновлення віртуального DOM.
-
getSnapshotBeforeUpdate(prevProps, prevState): Отримує знімок перед змінами (наприклад, положення скролу).
-
componentDidUpdate(prevProps, prevState, snapshot): Викликається після оновлення. Використовується для повторних запитів або роботи з DOM.
- Розмонтування (Unmounting): Коли компонент видаляється з DOM.
- componentWillUnmount(): Використовується для очищення ресурсів (наприклад, таймерів, підписок).
- Обробка помилок (Error Handling): Коли компонент викликає помилку.
-
static getDerivedStateFromError(error): Дозволяє оновити стан після помилки.
-
componentDidCatch(error, info): Логування помилок.
Фаза | Метод | Опис |
---|---|---|
Монтування | constructor() |
Ініціалізація стану та налаштування. |
getDerivedStateFromProps() |
Оновлення стану перед рендером. | |
render() |
Рендеринг JSX у віртуальний DOM. | |
componentDidMount() |
Виконується після додавання в DOM. | |
Оновлення | getDerivedStateFromProps() |
Оновлення стану перед рендером. |
shouldComponentUpdate() |
Визначає, чи потрібен повторний рендер. | |
render() |
Оновлює віртуальний DOM. | |
getSnapshotBeforeUpdate() |
Отримує знімок стану перед оновленням. | |
componentDidUpdate() |
Виконується після оновлення. | |
Розмонтування | componentWillUnmount() |
Очищення ресурсів перед видаленням. |
Обробка помилок | getDerivedStateFromError() |
Оновлює стан у разі помилки. |
componentDidCatch() |
Логування помилок. |
У функціональних компонентах замість методів життєвого циклу використовують хуки:
-
useEffect
замінюєcomponentDidMount
,componentDidUpdate
,componentWillUnmount
. -
useState
для управління станом.
11. Яка історія еволюції React?
- Ось коротка історія еволюції React:
- 2011
- React створений у Facebook для внутрішніх потреб. Його розробив інженер Джордан Волке, щоб вирішити проблему ефективного оновлення інтерфейсу.
- 2013
- Facebook випустив React як open-source бібліотеку. Спочатку спільнота зустріла її скептично через використання JSX, який здавався незвичним.
- 2015
-
Випущено React 0.14: розділено React і ReactDOM, що зробило бібліотеку більш модульною.
-
Facebook представив React Native, що дозволило створювати нативні мобільні додатки за допомогою React.
- 2016
- Випущено React 15. Основні оновлення торкнулися покращення продуктивності через новий рендеринг-движок.
- 2017
-
Випущено React 16 (Fiber). Fiber став новою архітектурою, що забезпечила покращену продуктивність та підтримку асинхронного рендерингу.
-
Додано підтримку порталів і помилкових кордонів (Error Boundaries).
- 2018
- Facebook представив React Hooks, які дозволили використовувати стан і методи життєвого циклу у функціональних компонентах. Це стало революцією у способі створення компонентів.
- 2019
-
Випущено React 16.8 з офіційною підтримкою хуків.
-
Покращено ефективність Concurrent Mode (експериментально).
- 2020
-
Випущено React 17. Головна мета — спрощення поступового оновлення React у великих проектах.
-
Додано підтримку сучасних інструментів і нових можливостей для роботи з JSX.
- 2022 і далі
- Випущено React 18. Головними нововведеннями стали Concurrent Rendering, новий API useTransition та useDeferredValue, які покращують продуктивність у динамічних додатках.
-
Від класових компонентів до функціональних з хуками.
-
Підтримка серверного рендерингу (SSR).
-
Concurrent Mode для плавного оновлення інтерфейсу.
-
Інтеграція React із мобільною розробкою через React Native.
React залишився популярним завдяки високій продуктивності, зручності використання та постійній підтримці від Facebook.
12. Які основні функції React?
- Декларативний підхід
- React дозволяє створювати інтерактивний інтерфейс, описуючи, як він повинен виглядати, а бібліотека сама оптимізує оновлення DOM.
- Компонентна структура
- Додаток будується з незалежних, багаторазових компонентів, які спрощують розробку, тестування та підтримку.
- Віртуальний DOM
- React використовує Virtual DOM для ефективного оновлення реального DOM, що значно покращує продуктивність.
- Односпрямований потік даних
- Дані передаються від батьківських компонентів до дочірніх через props, що спрощує управління станом.
- Хуки (Hooks)
- Дозволяють використовувати стан і методи життєвого циклу у функціональних компонентах.
- JSX
- Розширення JavaScript для опису UI в синтаксисі, схожому на HTML.
- React Native
- Можливість створювати нативні мобільні додатки з використанням тих самих принципів, що і для вебу.
- Екосистема
- Великий набір бібліотек та інструментів, таких як React Router, Redux, Context API.
- Підтримка серверного рендерингу (SSR)
- Дозволяє оптимізувати SEO та прискорювати початкове завантаження сторінок.
- Управління станом
- За допомогою useState, Context API, Redux чи інших бібліотек.
Ці функції роблять React потужною і гнучкою бібліотекою для створення сучасних додатків.
13. Яка різниця між елементом і компонентом?
Критерій | Елемент | Компонент |
---|---|---|
Визначення | Об'єкт, що описує, як має виглядати інтерфейс. | Функція або клас, який повертає React-елементи. |
Тип | Нероздільний (immutable). | Багаторазовий і може мати стан (state). |
Синтаксис створення | React.createElement або JSX (<div /> ). |
Функція або клас (function MyComponent() {} або class MyComponent extends React.Component {} ). |
Призначення | Представляє окремий вузол у DOM. | Інкапсулює логіку та структуру інтерфейсу. |
Можливість використання | Використовується для створення UI на базовому рівні. | Використовується для побудови складних структур із бізнес-логікою. |
Приклад | <h1>Hello</h1> |
function Hello() { return <h1>Hello</h1>; } |
- Елемент — це "будівельний блок", а компонент — "конструктор" для створення складних інтерфейсів.
14. Як створити компоненти в React?
- Функціональний компонент
- Це проста функція, яка повертає React-елементи.
function Greeting(props) {
return <h1>Hello, {props.name}!</h1>;
}
// Використання:
<Greeting name="John" />;
- Класовий компонент
- Це клас, який успадковується від React.Component і обов’язково має метод render.
class Greeting extends React.Component {
render() {
return <h1>Hello, {this.props.name}!</h1>;
}
}
// Використання:
<Greeting name="John" />;
-
Функціональні компоненти простіші та краще підходять для компонентів без стану.
-
Класові компоненти використовуються для складніших компонентів із власним станом або методами життєвого циклу.
Примітка: Сучасний підхід передбачає використання функціональних компонентів із хуками замість класових.
15. Коли використовувати компонент класу замість функціонального компонента?
- Класові компоненти використовувалися, коли потрібна була одна або кілька з цих функцій:
-
Робота зі станом (state): Раніше функціональні компоненти не підтримували локальний стан, тому використовували класи для цього. Сьогодні хуки (useState, useReducer) дозволяють функціональним компонентам працювати зі станом.
-
Методи життєвого циклу: Класи забезпечували доступ до методів, таких як componentDidMount, componentDidUpdate, componentWillUnmount, для управління компонентом на різних етапах його існування. Зараз це вирішується хуком useEffect.
-
Обробка складної логіки: Якщо логіка потребувала кількох методів і доступу до властивостей через this, класи виглядали логічним вибором. Сучасний підхід — хуки, які дозволяють інкапсулювати логіку.
- Починаючи з React 16.8, функціональні компоненти з хуками замінили потребу у класових компонентах. Тому в нових проєктах перевагу варто віддавати функціональним компонентам. Класи використовуються лише для підтримки застарілого коду.
16. Що таке чисті компоненти (Pure Components)?
- Чисті компоненти (Pure Components) — це спеціальні класові компоненти React, які автоматично оптимізують рендеринг. Вони реалізують поверхневе порівняння пропсів і стану, щоб запобігти зайвим оновленням, якщо значення пропсів або стану не змінилися.
- Чистий компонент створюється шляхом успадкування від React.PureComponent.
import React, { PureComponent } from "react";
class MyComponent extends PureComponent {
render() {
return <h1>Hello, {this.props.name}!</h1>;
}
}
// Використання:
<MyComponent name="John" />;
-
Виконує поверхневе порівняння (
shallow comparison
) пропсів і стану у методіshouldComponentUpdate
. -
Якщо пропси та стан не змінилися, компонент не рендериться повторно.
-
Коли пропси та стан є простими структурами (примітивні значення або неглибокі об'єкти).
-
Для підвищення продуктивності в компонентах, які часто оновлюються.
- Глибоке порівняння:
PureComponent
не враховує зміни всередині вкладених об'єктів або масивів.
- Наприклад, якщо ви оновлюєте об'єкт, але посилання на нього залишається незмінним, компонент не оновиться.
this.setState({ data: { ...this.state.data, key: "new value" } }); // Обхідна
- Не працює з функціональними компонентами.
- Альтернатива: використовувати
React.memo
для оптимізації функціональних компонентів.
const MyComponent = React.memo(function MyComponent(props) {
return <h1>Hello, {props.name}!</h1>;
});
17. Що таке стан (state) у React?
- Стан (state) у React — це об'єкт, який використовується для зберігання даних, що можуть змінюватися з часом, і впливають на рендеринг компонента. Стан дозволяє компонентам React бути динамічними і реагувати на події, введення користувача тощо.
-
Локальний для компонента: Стан доступний тільки в тому компоненті, де він визначений.
-
Змінюється асинхронно: React об'єднує виклики setState для оптимізації рендерингу.
-
Ініціалізується в конструкторі (для класових компонентів) або через useState (у функціональних компонентах).
class Counter extends React.Component {
constructor(props) {
super(props);
this.state = { count: 0 };
}
increment = () => {
this.setState({ count: this.state.count + 1 });
};
render() {
return (
<div>
<p>Count: {this.state.count}</p>
<button onClick={this.increment}>Increment</button>
</div>
);
}
}
import React, { useState } from "react";
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}
-
State — локальний для компонента і може змінюватися.
-
Props — передаються зовні і є незмінними (immutable).
18. Що таке пропси (props) в React?
- Пропси (props) в React — це об'єкт, який містить дані, що передаються від батьківського компонента до дочірнього. Вони використовуються для налаштування компонентів і є незмінними (immutable).
-
Передаються зверху вниз (унідіrectional data flow) — від батьківського компонента до дочірнього.
-
Незмінні — компонент не може змінювати отримані пропси.
-
Динамічні — значення пропсів можуть змінюватися, якщо змінюються дані в батьківському компоненті.
- У функціональному компоненті:
function Welcome(props) {
return <h1>Hello, {props.name}!</h1>;
}
// Використання:
<Welcome name="John" />;
- У класовому компоненті:
Копіювати;
Редагувати;
class Welcome extends React.Component {
render() {
return <h1>Hello, {this.props.name}!</h1>;
}
}
// Використання:
<Welcome name="Jane" />;
function App() {
return (
<div>
<Welcome name="Alice" />
<Welcome name="Bob" />
</div>
);
}
- Результат:
Hello, Alice!
Hello, Bob!
function Welcome({ name }) {
return <h1>Hello, {name}!</h1>;
}
function Welcome({ name = "Guest" }) {
return <h1>Hello, {name}!</h1>;
}
// Використання:
<Welcome />; // Виведе: Hello, Guest!
- Пропси забезпечують компонентам React гнучкість і можливість повторного використання.
19. Яка різниця між обробкою подій HTML і React?
Критерій | HTML | React |
---|---|---|
Прив’язка події | Вказується як атрибут: <button onclick="handler()"> . |
Використовується camelCase: <button onClick={handler}> . |
Тип функції | Посилання на глобальну функцію або рядок із JavaScript-кодом. | Прив’язка до функції компонента (зазвичай вказується як метод або стрілочна функція). |
Додавання слухачів подій | Обробники додаються вручну через addEventListener . |
React автоматично керує прив’язкою через віртуальний DOM. |
Контекст this |
Потрібно вручну встановлювати контекст, якщо використовується в класах. | React автоматично зберігає правильний контекст у функціональних компонентах. |
Стандартна поведінка | Необхідно явно викликати return false для припинення поведінки. |
Використовується event.preventDefault() для зупинки стандартної поведінки. |
Сумісність | Обробляє лише реальні DOM-події. | Використовує "SyntheticEvent", що є обгорткою над нативними подіями. |
Кросбраузерність | Потрібно вручну враховувати відмінності між браузерами. | React забезпечує кросбраузерну сумісність через SyntheticEvent. |
Прив’язка контексту | Часто вимагає використання bind . |
У класових компонентах потрібен bind , у функціональних — ні. |
<button onclick="alert('Clicked!')">Click me</button>
function handleClick() {
alert("Clicked!");
}
function App() {
return <button onClick={handleClick}>Click me</button>;
}
- React використовує обгортку над нативними подіями, яка нормалізує поведінку між різними браузерами та підвищує продуктивність.
20. Які ключові переваги використання React?
-
Швидкість: Завдяки Virtual DOM React мінімізує взаємодії з реальним DOM, що підвищує продуктивність.
-
Компонентний підхід: Код розбивається на багаторазово використовувані компоненти, що спрощує розробку та підтримку.
-
Одностороння передача даних: Потік даних у React відбувається в одному напрямку (зверху вниз), що полегшує дебагінг.
-
Велика спільнота: React має величезну екосистему бібліотек, інструментів і розширень.
-
Сумісність із мобільною розробкою: Використовуючи React Native, можна створювати кросплатформені мобільні додатки.
-
JSX: Синтаксис, який дозволяє писати JavaScript разом із HTML, що підвищує читабельність коду.
-
Підтримка хуків: Спрощення роботи зі станом та життєвим циклом у функціональних компонентах.
-
SEO-дружність: Серверний рендеринг за допомогою інструментів, таких як Next.js, покращує SEO-оптимізацію.
-
Гнучкість: React можна інтегрувати в будь-який проєкт або фреймворк без значних змін у коді.
-
React DevTools: Інструмент для налагодження, який дозволяє зручно аналізувати компоненти та стан додатка.
21. Що таке синтетичні події в React?
- Синтетичні події (Synthetic Events) у React — це обгортки для нативних DOM-подій, які надають однаковий інтерфейс для обробки подій на різних браузерах. React створює SyntheticEvent для кожної події, що дозволяє працювати з подіями в уніфікованому вигляді, забезпечуючи кросбраузерну сумісність і покращуючи продуктивність.
-
Кросбраузерність: SyntheticEvent абстрагує особливості роботи з подіями в різних браузерах, забезпечуючи однакову поведінку.
-
Оптимізація: SyntheticEvent використовує пул об'єктів, що дозволяє зменшити витрати на створення нових об'єктів подій.
-
Одноразове використання: Після обробки події об'єкт SyntheticEvent "повертається" в пул, і його не можна використовувати після цього. Для асинхронних операцій потрібно зберігати подію в окремій змінній.
-
Інтерфейс: SyntheticEvent має такі ж методи, як і стандартні нативні події (наприклад,
preventDefault()
,stopPropagation()
).
function handleClick(event) {
// SyntheticEvent має доступ до методу preventDefault()
event.preventDefault();
console.log("Button clicked!");
}
function App() {
return <button onClick={handleClick}>Click me</button>;
}
- У цьому прикладі event — це SyntheticEvent, який працює аналогічно до нативної події, але з покращеними можливостями.
22. Як оновити стан компонента?
- У React стан компонента оновлюється за допомогою методу
setState
у класових компонентах абоuseState
у функціональних компонентах.
-
Стан оновлюється через
this.setState()
. -
Приклад:
class Counter extends React.Component {
constructor(props) {
super(props);
this.state = { count: 0 };
}
increment = () => {
this.setState({ count: this.state.count + 1 });
};
render() {
return (
<div>
<p>Count: {this.state.count}</p>
<button onClick={this.increment}>Increment</button>
</div>
);
}
}
-
Стан оновлюється через функцію, отриману з
useState
. -
Приклад:
import React, { useState } from "react";
function Counter() {
const [count, setCount] = useState(0);
const increment = () => {
setCount(count + 1);
};
return (
<div>
<p>Count: {count}</p>
<button onClick={increment}>Increment</button>
</div>
);
}
- Асинхронність:
setState
іuseState
працюють асинхронно. Для оновлення стану на основі попереднього значення використовуйте функціональний підхід:
this.setState((prevState) => ({ count: prevState.count + 1 }));
setCount((prevCount) => prevCount + 1);
- Не оновлюйте стан напряму: Модифікація стану без використання
setState
абоuseState
не викликає повторний рендеринг.
23. Що таке вбудовані умовні вирази?
- Вбудовані умовні вирази в JavaScript (зокрема у React) — це механізми, що дозволяють вбудовувати умови безпосередньо в JSX для умовного рендерингу елементів або компонентів. Це дозволяє зробити код компактнішим і зручнішим для розуміння.
- Оператор умови (тернарний оператор): Це один із найпоширеніших способів для умовного рендерингу елементів в JSX. Він має такий синтаксис:
умова ? вираз_якщо_правда : вираз_якщо_неправда;
Приклад:
const isLoggedIn = true;
function App() {
return <div>{isLoggedIn ? <p>Welcome, User!</p> : <p>Please log in</p>}</div>;
}
- Логічний оператор AND (&&): Цей метод дозволяє відображати компонент або елемент тільки тоді, коли умова є true. Якщо умова не виконується, нічого не буде рендеритись.
Приклад:
const isUserAdmin = true;
function App() {
return <div>{isUserAdmin && <p>You have admin privileges</p>}</div>;
}
- У цьому випадку
<p>You have admin privileges</p>
буде відображено лише, якщоisUserAdmin
— цеtrue
.
- IF перед поверненням JSX: Можна також використовувати звичайні умовні оператори if перед поверненням JSX, коли умова має бути більш складною або коли потрібно виконати декілька умовних дій.
Приклад:
function App() {
let content;
if (isLoggedIn) {
content = <p>Welcome back!</p>;
} else {
content = <p>Please sign in.</p>;
}
return <div>{content}</div>;
}
-
Вбудовані умовні вирази дозволяють писати більш чистий і компактний код.
-
Вони покращують читаємість і зменшують використання додаткових умовних конструкцій.
- В React не можна використовувати інструкції
if
безпосередньо в JSX. Однак можна застосувати їх перед поверненням JSX.
24. Як обробляти події в React?
- В React обробка подій працює схоже на стандартний JavaScript, але з деякими відмінностями. Події в React є синтетичними, що означає, що вони мають абстракцію поверх реальних подій браузера, що забезпечує крос-браузерну сумісність.
-
Синтетичні події: Всі події в React обгорнуті в об'єкт SyntheticEvent, який є крос-браузерною реалізацією стандартних подій DOM. Це дозволяє обробляти події однаково в усіх браузерах.
-
Використання camelCase для подій: У React події записуються у форматі camelCase замість стандартного нижнього регістру (наприклад,
onClick
замістьonclick
). -
Передача функцій як обробників подій: Події в React обробляються за допомогою функцій, які передаються через атрибути компонентів.
import React, { Component } from "react";
class MyButton extends Component {
handleClick = () => {
alert("Button clicked!");
};
render() {
return <button onClick={this.handleClick}>Click Me</button>;
}
}
export default MyButton;
import React, { useState } from "react";
function MyButton() {
const [count, setCount] = useState(0);
const handleClick = () => {
setCount(count + 1);
};
return <button onClick={handleClick}>Clicked {count} times</button>;
}
export default MyButton;
-
Не потрібно використовувати
addEventListener
: В React немає необхідності вручну додавати або видаляти обробники подій. Це автоматично керується бібліотекою React. -
Збереження контексту в методах класових компонентів: Якщо методи класових компонентів використовуються як обробники подій, контекст (
this
) потрібно прив'язати або через стрілкові функції, або вручну в конструкторі.
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = { count: 0 };
// Прив'язка методу
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
this.setState({ count: this.state.count + 1 });
}
render() {
return (
<button onClick={this.handleClick}>
Clicked {this.state.count} times
</button>
);
}
}
- Передача параметрів у функцію обробника: Якщо потрібно передати додаткові аргументи в обробник події, можна використовувати стрілкові функції або функції з параметрами.
function MyButton({ label }) {
const handleClick = (event, label) => {
console.log(label);
};
return (
<button onClick={(event) => handleClick(event, label)}>{label}</button>
);
}
- Всі події, що відбуваються в React, працюють за принципом делегування подій, де один обробник подій реєструється для всього дерева компонентів і пропускається через React SyntheticEvent.
25. Що таке (key) prop і яка перевага його використання в масивах елементів?
- У React prop
key
використовується для ідентифікації кожного елементу в списках або масивах, щоб допомогти React ефективно керувати рендерами при зміні або оновленні елементів списку. Це важливо для оптимізації процесу рендерингу, особливо коли список змінюється (елементи додаються, видаляються або змінюються).
-
Унікальність: Кожен елемент у списку повинен мати унікальний
key
. Це дозволяє React відстежувати, які елементи змінюються, додаються або видаляються, а також зберігати їх стан між рендерами. -
Оптимізація рендерингу: Використання key дозволяє React мінімізувати кількість ререндерів, виконуючи тільки необхідні зміни в DOM. Без
key
, React має важчий час для відстеження змін, що призводить до повного повторного рендерингу списку, навіть якщо тільки один елемент змінився. -
Природа key: Prop
key
не передається в компонент, тому його не можна використовувати для відображення значень в UI. Це тільки інтерналізована властивість, що використовується React для відстеження елементів.
const items = ["apple", "banana", "cherry"];
function FruitList() {
return (
<ul>
{items.map((item, index) => (
<li key={index}>{item}</li> // Важливо: використовувати унікальний key
))}
</ul>
);
}
-
Неправильне використання: Якщо у якості key використовувати неунікальні значення (наприклад, однаковий index), React не зможе коректно відстежувати зміни, і це призведе до помилок в рендерингу.
-
Ідеальний key: Зазвичай, якщо є унікальний ідентифікатор елемента (наприклад, id), він повинен бути використаний як key замість індексу масиву.
const items = [
{ id: 1, name: "apple" },
{ id: 2, name: "banana" },
{ id: 3, name: "cherry" },
];
function FruitList() {
return (
<ul>
{items.map((item) => (
<li key={item.id}>{item.name}</li> // Краще використовувати унікальні id
))}
</ul>
);
}
-
Покращує продуктивність рендерингу.
-
Дозволяє React оптимально оновлювати тільки змінені елементи, а не весь список.
-
Забезпечує коректну обробку стану елементів при їх переміщенні, видаленні або оновленні.
Таким чином, використання key
є важливим для ефективної роботи з масивами елементів у React.
26. Що таке умовний рендеринг у React?
- Умовний рендеринг у React — це процес, при якому компонент рендерить різний вміст залежно від певних умов. Це дозволяє динамічно змінювати відображення компонента на основі стану, пропсів або інших факторів.
- Оператор
if
: Можна використовувати стандартний оператор if для вирішення, що рендерити.
function Greeting(props) {
if (props.isLoggedIn) {
return <h1>Welcome back!</h1>;
}
return <h1>Please sign up.</h1>;
}
- Тернарний оператор: Часто використовують тернарний оператор для коротших умовних виразів.
function Greeting(props) {
return <h1>{props.isLoggedIn ? "Welcome back!" : "Please sign up."}</h1>;
}
- Логічне І (&&) для рендерингу: Можна використати логічний оператор
&&
, щоб рендерити елемент лише за умови, що вираз зліва від нього є істинним.
function Notifications(props) {
return (
<div>
{props.unreadMessages.length > 0 && (
<h2>You have {props.unreadMessages.length} unread messages.</h2>
)}
</div>
);
}
- Це працює так: якщо props.unreadMessages.length більше за 0, то відобразиться повідомлення, інакше нічого не буде відображено.
- Використання
return
з умовним оператором: Ви можете використовувати return для умовного рендерингу на основі різних умов, як в прикладі зif
або тернарним оператором.
-
Дозволяє динамічно змінювати вміст залежно від стану або пропсів.
-
Покращує гнучкість і можливість відображення різного контенту для різних користувачів або ситуацій.
function UserStatus(props) {
return (
<div>
{props.isLoggedIn ? (
<button onClick={props.logout}>Log Out</button>
) : (
<button onClick={props.login}>Log In</button>
)}
</div>
);
}
- Тут кнопка змінюється в залежності від того, чи користувач увійшов в систему.
27. Що таке React Fiber?
- React Fiber — це нова архітектура рендерингу в React, представлена з версії 16. Вона була розроблена для покращення продуктивності, підтримки асинхронного рендерингу та забезпечення більш гнучкого управління оновленнями UI.
- Покращена продуктивність:
- Fiber дозволяє React зберігати стан виконання рендеру, що дає можливість переривати і продовжувати рендеринг за потреби. Це важливо для великих додатків, де складні обчислення можуть уповільнювати рендеринг.
- Асинхронний рендеринг:
- React Fiber підтримує асинхронний рендеринг, що дозволяє виконувати рендеринг по частинах, покращуючи відгук додатку, особливо в складних інтерфейсах. Завдяки цьому можна виконувати рендеринг без блокування головного потоку.
- Пріоритет оновлень:
- Fiber дозволяє надавати пріоритет різним типам оновлень (наприклад, рендеринг анімацій може бути високим пріоритетом, а рендеринг змін стану — низьким). Це дозволяє React управляти складними оновленнями більш ефективно.
- Розбиття рендерингу на підзадачі:
- У старих версіях React всі зміни оброблялись в одному кроці. Fiber розбиває рендеринг на дрібніші підзадачі, що дозволяє React виконувати роботу поетапно і дає змогу обробляти інші важливі операції (наприклад, обробку подій) між етапами.
- Покращена підтримка анімацій та переходів:
- Завдяки асинхронному рендерингу, React може більш ефективно керувати анімаціями, що робить переходи між станами плавними та без затримок.
-
У старих версіях React весь процес рендерингу був синхронним: від початку до кінця. Це означало, що важкі обчислення блокували рендеринг інтерфейсу. У React Fiber рендеринг розділений на маленькі задачі, які можуть бути виконані асинхронно. Якщо необхідно, React може перервати одну задачу і продовжити виконання пізніше, не блокуючи інші операції (наприклад, оновлення UI або обробку подій).
-
Fiber дозволяє React:
-
Розподіляти виконання рендерингу для покращення продуктивності.
-
Реалізувати асинхронні оновлення UI.
-
Краще керувати пріоритетами та обробкою важких обчислень, що особливо важливо для складних інтерфейсів і додатків.
-
-
Покращення відгуку додатків.
-
Можливість обробляти важкі операції без затримок для користувача.
-
Краще управління анімаціями та переходами.
React Fiber — це внутрішнє оновлення, яке змінило спосіб, яким React працює з рендерингом, покращуючи загальну продуктивність додатків.
28. Як передаються дані між компонентами у React
- У React дані передаються між компонентами за ієрархією наступним чином:
-
Для передачі даних вниз використовується props. Батьківський компонент передає значення або функції через атрибути дочірньому компоненту.
-
Приклад:
function ParentComponent() {
const data = "Hello from Parent";
return <ChildComponent message={data} />;
}
function ChildComponent({ message }) {
return <p>{message}</p>;
}
-
message
передає значенняdata
в дочірній компонентChildComponent
. -
У дочірньому компоненті доступ до пропсів відбувається через параметр функції або
this.props
у класовому компоненті.
-
Дані передаються вгору за допомогою callback-функцій. Батьківський компонент передає функцію дочірньому, а той викликає її з потрібними даними.
-
Приклад:
function ParentComponent() {
const handleData = (childData) => {
console.log("Data from child:", childData);
};
return <ChildComponent sendData={handleData} />;
}
function ChildComponent({ sendData }) {
const data = "Hello from Child";
return <button onClick={() => sendData(data)}>Send Data</button>;
}
-
Батьківський компонент передає функцію
handleData
в пропсsendData
. -
Дочірній компонент викликає
sendData
, передаючи значенняdata
.
- Контекст (Context API):
-
Для передачі даних глибоко по ієрархії без пропсів.
-
Підходить для глобального стану, наприклад, теми чи мови інтерфейсу.
const MyContext = React.createContext();
function ParentComponent() {
const data = "Hello from Context";
return (
<MyContext.Provider value={data}>
<ChildComponent />
</MyContext.Provider>
);
}
function ChildComponent() {
const contextData = React.useContext(MyContext);
return <p>{contextData}</p>;
}
- Менеджери стану (Redux, Zustand, MobX):
- Для передачі даних у великих додатках через єдиний глобальний стан.
- Custom Hooks:
- Використовується для спільного використання логіки між компонентами.
29. Що таке контрольовані компоненти (Controlled Components)?
-
Контрольовані компоненти — це компоненти, в яких React контролює стан форми через
state
. Значення полів форми (наприклад,<input>
,<textarea>
,<select>
) прив'язуються до стану компонента, і зміни обробляються через події. -
Як це працює:
-
Компонент зберігає значення форми у своєму
state
. -
Зміни значення полів форми обробляються через подію
onChange
. -
Значення форми оновлюється, використовуючи
setState
.
- Приклад:
import React, { useState } from "react";
function ControlledForm() {
const [inputValue, setInputValue] = useState("");
const handleChange = (event) => {
setInputValue(event.target.value); // Оновлюємо стан
};
const handleSubmit = (event) => {
event.preventDefault();
console.log("Submitted value:", inputValue);
};
return (
<form onSubmit={handleSubmit}>
<label>
Enter text:
<input
type="text"
value={inputValue} // Значення контролюється state
onChange={handleChange} // Обробка змін
/>
</label>
<button type="submit">Submit</button>
</form>
);
}
export default ControlledForm;
-
Одне джерело істини: Значення форми синхронізоване зі станом компонента.
-
Гнучкість: Легко валідовувати та модифікувати дані форми.
-
Прозорість: Стан форми зрозумілий та передбачуваний.
-
У контрольованих компонентах значення форми контролюється React через
state
. -
У неконтрольованих компонентах значення зберігається в самому DOM, і доступ до нього здійснюється через
ref
. -
Неконтрольований приклад для порівняння:
function UncontrolledForm() {
const inputRef = React.useRef();
const handleSubmit = (event) => {
event.preventDefault();
console.log("Submitted value:", inputRef.current.value);
};
return (
<form onSubmit={handleSubmit}>
<label>
Enter text:
<input type="text" ref={inputRef} />
</label>
<button type="submit">Submit</button>
</form>
);
}
- Контрольовані компоненти надають кращий контроль та передбачуваність у роботі з формами.
30. Які підходи використовуються для виконання HTTP-запитів у React?
- React не має вбудованого API для виконання HTTP-запитів, але ви можете використовувати сторонні бібліотеки або стандартні засоби JavaScript. Ось основні підходи:
- Використання Fetch API
-
Стандартний інструмент для виконання HTTP-запитів у JavaScript.
-
Приклад:
import React, { useEffect, useState } from "react";
function FetchExample() {
const [data, setData] = useState([]);
const [error, setError] = useState(null);
useEffect(() => {
fetch("https://jsonplaceholder.typicode.com/posts")
.then((response) => {
if (!response.ok) {
throw new Error("Network response was not ok");
}
return response.json();
})
.then((data) => setData(data))
.catch((error) => setError(error.message));
}, []);
return (
<div>
{error ? (
<p>Error: {error}</p>
) : (
<ul>
{data.map((post) => (
<li key={post.id}>{post.title}</li>
))}
</ul>
)}
</div>
);
}
export default FetchExample;
- Використання Axios
-
Бібліотека для виконання HTTP-запитів з простішим синтаксисом та вбудованою підтримкою проміжних обробників (interceptors).
-
Приклад:
import React, { useEffect, useState } from "react";
import axios from "axios";
function AxiosExample() {
const [data, setData] = useState([]);
const [error, setError] = useState(null);
useEffect(() => {
axios
.get("https://jsonplaceholder.typicode.com/posts")
.then((response) => setData(response.data))
.catch((error) => setError(error.message));
}, []);
return (
<div>
{error ? (
<p>Error: {error}</p>
) : (
<ul>
{data.map((post) => (
<li key={post.id}>{post.title}</li>
))}
</ul>
)}
</div>
);
}
export default AxiosExample;
- React Query (TanStack Query)
-
Бібліотека для управління станом даних, отриманих через HTTP-запити. Підтримує кешування, повторні спроби та оновлення даних.
-
Приклад:
import React from "react";
import { useQuery } from "react-query";
import axios from "axios";
function ReactQueryExample() {
const { data, error, isLoading } = useQuery("posts", async () => {
const response = await axios.get(
"https://jsonplaceholder.typicode.com/posts"
);
return response.data;
});
if (isLoading) return <p>Loading...</p>;
if (error) return <p>Error: {error.message}</p>;
return (
<ul>
{data.map((post) => (
<li key={post.id}>{post.title}</li>
))}
</ul>
);
}
export default ReactQueryExample;
- GraphQL (Apollo Client)
-
Для роботи з GraphQL API використовується Apollo Client.
-
Приклад:
import React from "react";
import { useQuery, gql } from "@apollo/client";
const GET_POSTS = gql`
query GetPosts {
posts {
id
title
}
}
`;
function ApolloExample() {
const { loading, error, data } = useQuery(GET_POSTS);
if (loading) return <p>Loading...</p>;
if (error) return <p>Error: {error.message}</p>;
return (
<ul>
{data.posts.map((post) => (
<li key={post.id}>{post.title}</li>
))}
</ul>
);
}
export default ApolloExample;
- Custom Hooks
-
Ви можете створювати власні хуки для повторного використання логіки запитів.
-
Приклад:
import { useState, useEffect } from "react";
function useFetch(url) {
const [data, setData] = useState(null);
const [error, setError] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
fetch(url)
.then((response) => response.json())
.then((data) => {
setData(data);
setLoading(false);
})
.catch((error) => {
setError(error.message);
setLoading(false);
});
}, [url]);
return { data, error, loading };
}
export default useFetch;
-
Fetch API: для простих запитів.
-
Axios: якщо потрібна більша гнучкість (interceptors, тайм-аути).
-
React Query: для управління кешем даних.
-
GraphQL/Apollo Client: якщо API побудоване на GraphQL.
-
Custom Hooks: для повторного використання логіки запитів.
31. Що таке неконтрольовані компоненти (Uncontrolled Components)?
- Неконтрольовані компоненти (Uncontrolled Components) — це компоненти, які зберігають свій стан у DOM, а не у внутрішньому стані React-компонента. Доступ до значень таких компонентів здійснюється за допомогою рефів (refs).
-
Стан керується DOM: значення полів зберігаються та оновлюються безпосередньо у DOM.
-
Менше інтеграції з React: вони не використовують useState або будь-які інші засоби React для зберігання стану.
-
Застосування рефів: для отримання доступу до значення полів форми використовується ref.
import React, { useRef } from "react";
function UncontrolledForm() {
const inputRef = useRef(null);
const handleSubmit = (event) => {
event.preventDefault();
alert(`Введене значення: ${inputRef.current.value}`);
};
return (
<form onSubmit={handleSubmit}>
<label>
Ім'я:
<input type="text" ref={inputRef} />
</label>
<button type="submit">Відправити</button>
</form>
);
}
export default UncontrolledForm;
-
Якщо потрібна мінімальна інтеграція React із DOM.
-
Якщо значення форми обробляються сторонніми бібліотеками.
-
Якщо необхідна проста форма без складної логіки.
-
Простота реалізації для простих форм.
-
Менше коду для управління станом.
-
Менший контроль над значеннями.
-
Складніше реалізувати валідацію або синхронізацію даних.
-
Менш React-орієнтований підхід.
32. Способи стилізації в React-компонентах?
- Inline-стилі Стилі передаються безпосередньо у вигляді об’єкта через атрибут
style
.
function InlineStyle() {
const style = {
color: "blue",
fontSize: "20px",
};
return <h1 style={style}>Привіт, React!</h1>;
}
- CSS-файли Використання звичайних CSS-файлів, які імпортуються в компонент.
import "./styles.css";
function CSSFile() {
return <h1 className="heading">Привіт, React!</h1>;
}
Копіювати
Редагувати
/* styles.css */
.heading {
color: blue;
font-size: 20px;
}
- CSS-модулі Створюють локально ізольовані стилі для кожного компонента.
import styles from "./styles.module.css";
function CSSModule() {
return <h1 className={styles.heading}>Привіт, React!</h1>;
}
/* styles.module.css */
.heading {
color: blue;
font-size: 20px;
}
- Styled Components Використання бібліотеки styled-components для написання стилів у JavaScript.
npm install styled-components
import styled from "styled-components";
const Heading = styled.h1`
color: blue;
font-size: 20px;
`;
function StyledComponent() {
return <Heading>Привіт, React!</Heading>;
}
- Emotion Альтернативна бібліотека для стилізації, схожа на styled-components.
npm install @emotion/react @emotion/styled
/**_ @jsxImportSource @emotion/react */
import { css } from "@emotion/react";
const style = css`
color: blue;
font-size: 20px;
`;
function EmotionStyle() {
return <h1 css={style}>Привіт, React!</h1>;
}
- CSS-in-JS Створення динамічних стилів у звичайних JavaScript-файлах.
function CSSInJS({ isBlue }) {
const style = {
color: isBlue ? "blue" : "red",
fontSize: "20px",
};
return <h1 style={style}>Привіт, React!</h1>;
}
- Tailwind CSS Фреймворк класів утиліт для стилізації компонентів.
function TailwindExample() {
return <h1 className="text-blue-500 text-2xl">Привіт, React!</h1>;
}
- Налаштування Tailwind CSS: додайте залежності та налаштуйте конфігурацію.
- Sass/SCSS Розширений CSS із підтримкою змінних, міксинів та вкладеності.
npm install sass
import "./styles.scss";
function SCSSExample() {
return <h1 className="heading">Привіт, React!</h1>;
}
/* styles.scss */
.heading {
color: blue;
font-size: 20px;
}
-
Масштабності проекту.
-
Потреби в ізоляції стилів.
-
Переваг команди.
33. Яка різниця між createElement і cloneElement?
Метод | Опис | Основне застосування |
---|---|---|
React.createElement |
Створює новий елемент React. Приймає тип елемента, пропси та дочірні елементи як аргументи. | Використовується для створення елементів React з нуля, зазвичай під час рендерингу JSX. |
React.cloneElement |
Клонує існуючий елемент React, дозволяючи змінити його пропси або дочірні елементи. | Використовується для створення змінених копій вже існуючих елементів React. |
React.createElement
const element = React.createElement(
"div",
{ className: "example" },
"Привіт, React!"
);
Результат: створюється <div class="example">Привіт, React!</div>
.
React.cloneElement
const originalElement = <button className="primary">Натисни</button>;
const clonedElement = React.cloneElement(originalElement, {
className: "secondary",
});
Результат: клон <button class="secondary">Натисни</button>
зі зміненим класом.
-
createElement
: створює абсолютно новий елемент. -
cloneElement
: працює на основі вже існуючого елемента, дозволяючи змінювати його властивості або вміст.
34. Що таке компоненти вищого порядку (Higher-Order components)?
- Компонент вищого порядку — це функція, яка приймає компонент як вхідний аргумент і повертає новий компонент, розширюючи його функціональність.
const EnhancedComponent = higherOrderComponent(WrappedComponent);
-
Приймає компонент як аргумент.
-
Повертає новий компонент із додатковими властивостями чи поведінкою.
-
Дозволяє перевикористовувати логіку у різних компонентах.
- HOC для додавання стану до компонента:
import React, { useState } from "react";
// HOC: додає логіку роботи зі станом
function withCounter(WrappedComponent) {
return function EnhancedComponent(props) {
const [count, setCount] = useState(0);
const increment = () => setCount(count + 1);
return <WrappedComponent count={count} increment={increment} {...props} />;
};
}
// Компонент, який буде розширено
function Button({ count, increment }) {
return <button onClick={increment}>Clicked {count} times</button>;
}
// Використання HOC
const EnhancedButton = withCounter(Button);
export default EnhancedButton;
-
Авторизація (Authentication) — обгортання компонентів для перевірки прав доступу.
-
Обробка даних — підключення до API чи обробка стану.
-
Логування — додавання журналювання дій компонентів.
-
Може створювати глибокі вкладення (component tree), якщо використовувати забагато HOC.
-
Ускладнює читабельність через обгортання компонентів.
HOC — потужний інструмент для повторного використання логіки, але в сучасних додатках їх часто замінюють React Hooks.
35. Що таке Lifting State Up у React?
Lifting State Up — це підхід у React, коли стан (state) піднімається до найближчого спільного предка компонентів, яким потрібно спільно використовувати цей стан. Це дозволяє організувати єдине джерело правди для управління даними між компонентами.
-
Компоненти, які мають спільно використовувати дані, не повинні кожен мати власний стан.
-
Стан піднімається до батьківського компонента, який передає дані через props дочірнім компонентам.
-
Батьківський компонент зберігає стан.
-
Він передає стан та функції для оновлення стану своїм дочірнім компонентам через props.
-
Дочірні компоненти повідомляють батька про зміни, використовуючи передані функції.
import React, { useState } from "react";
function TemperatureInput({ temperature, onTemperatureChange }) {
return (
<fieldset>
<legend>Enter temperature in Celsius:</legend>
<input
type="number"
value={temperature}
onChange={(e) => onTemperatureChange(e.target.value)}
/>
</fieldset>
);
}
function BoilingVerdict({ celsius }) {
return celsius >= 100 ? (
<p>The water will boil.</p>
) : (
<p>The water won't boil.</p>
);
}
function Calculator() {
const [temperature, setTemperature] = useState("");
return (
<div>
<TemperatureInput
temperature={temperature}
onTemperatureChange={setTemperature}
/>
<BoilingVerdict celsius={parseFloat(temperature)} />
</div>
);
}
export default Calculator;
-
Забезпечує єдине джерело правди для стану.
-
Полегшує синхронізацію даних між компонентами.
-
Робить компоненти більш передбачуваними та повторно використовуваними.
36. Як створити форму в React?
- Форми в React створюються за допомогою елементів
<form>
та відповідних контролів, як-от<input>
,<textarea>
,<select>
. Реактивність форм забезпечується керованими або некерованими компонентами.
- Керовані компоненти використовують стан (state) для відстеження значення полів форми.
import React, { useState } from "react";
function ControlledForm() {
const [name, setName] = useState("");
const [email, setEmail] = useState("");
const handleSubmit = (e) => {
e.preventDefault();
console.log("Submitted:", { name, email });
};
return (
<form onSubmit={handleSubmit}>
<label>
Name:
<input
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
/>
</label>
<br />
<label>
Email:
<input
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
</label>
<br />
<button type="submit">Submit</button>
</form>
);
}
export default ControlledForm;
-
Особливості:
-
Кожне поле контролюється через
state
. -
Легко синхронізувати та обробляти дані форми.
-
- Некеровані компоненти використовують реф (
ref
) для прямого доступу до DOM-елементів.
import React, { useRef } from "react";
function UncontrolledForm() {
const nameRef = useRef();
const emailRef = useRef();
const handleSubmit = (e) => {
e.preventDefault();
console.log("Submitted:", {
name: nameRef.current.value,
email: emailRef.current.value,
});
};
return (
<form onSubmit={handleSubmit}>
<label>
Name:
<input type="text" ref={nameRef} />
</label>
<br />
<label>
Email:
<input type="email" ref={emailRef} />
</label>
<br />
<button type="submit">Submit</button>
</form>
);
}
export default UncontrolledForm;
-
Особливості:
-
Доступ до значень здійснюється через ref.
-
Підходить для простих форм.
-
- Керована форма:
-
Використовує
state
. -
Більш підходить для складних форм, що потребують валідації або синхронізації.
- Некерована форма:
-
Використовує
ref
. -
Простий підхід без складної логіки управління станом.
Вибір підходу залежить від складності форми та потреб у взаємодії з її полями.
37. Що таке children prop?
children
— це спеціальний пропс у React, який використовується для передачі вкладених елементів або компонентів у компонент-обгортку.
- Коли ви передаєте дочірній вміст між відкриваючим і закриваючим тегами компонента, цей вміст автоматично передається як значення
props.children
.
- Компонент-обгортка:
function Wrapper({ children }) {
return <div className="wrapper">{children}</div>;
}
- Використання:
function App() {
return (
<Wrapper>
<h1>Hello, World!</h1>
<p>This is a paragraph inside the wrapper.</p>
</Wrapper>
);
}
- Результат:
<div class="wrapper">
<h1>Hello, World!</h1>
<p>This is a paragraph inside the wrapper.</p>
</div>
-
Гнучкість: Можна передавати будь-який тип даних: текст, JSX, компоненти, масиви елементів.
-
Повторне використання: Компонент-обгортка може динамічно відображати різний вміст.
-
Структурованість: Допомагає створювати компоненти з вкладеною структурою.
Іноді children
використовується як функція для динамічної передачі даних:
function List({ items, children }) {
return <ul>{items.map((item) => children(item))}</ul>;
}
function App() {
return (
<List items={["Apple", "Banana", "Cherry"]}>
{(item) => <li key={item}>{item}</li>}
</List>
);
}
- Результат:
<ul>
<li>Apple</li>
<li>Banana</li>
<li>Cherry</li>
</ul>
children
— це потужний інструмент для створення універсальних і багаторазових компонентів у React.
38. Як реалізувати додавання класу за умовою в React?
- В React умовне додавання класів до елементів зазвичай здійснюється через атрибут
className
і використання тернарного оператора або функцій для визначення умов.
- Тернарний оператор
function MyComponent({ isActive }) {
return (
<div className={isActive ? "active-class" : "inactive-class"}>Hello</div>
);
}
- Якщо
isActive
дорівнюєtrue
, до елемента буде додано класactive-class
. - Інакше —
inactive-class
.
- Шаблонні рядки
function MyComponent({ isHighlighted }) {
return (
<div className={`base-class ${isHighlighted ? "highlighted-class" : ""}`}>
Hello
</div>
);
}
- Завжди додається
base-class
. - Якщо
isHighlighted
дорівнює true, додається ще йhighlighted-class
.
- Бібліотека
clsx
clsx
допомагає працювати з класами більш елегантно.
npm install clsx
import clsx from "clsx";
function MyComponent({ isActive, isDisabled }) {
return (
<div
className={clsx("base-class", {
"active-class": isActive,
"disabled-class": isDisabled,
})}
>
Hello
</div>
);
}
clsx
дозволяє легко додавати кілька класів на основі умов.
- Бібліотека
classnames
- Схожа на
clsx
, але має більше можливостей.
npm install classnames
import classNames from "classnames";
function MyComponent({ isActive, isDisabled }) {
return (
<div
className={classNames("base-class", {
"active-class": isActive,
"disabled-class": isDisabled,
})}
>
Hello
</div>
);
}
- Винесення логіки в окрему функцію
function getClassName(isActive, isDisabled) {
let className = "base-class";
if (isActive) className += " active-class";
if (isDisabled) className += " disabled-class";
return className;
}
function MyComponent({ isActive, isDisabled }) {
return <div className={getClassName(isActive, isDisabled)}>Hello</div>;
}
- Логіка визначення класів стає більш читабельною та може бути перевикористана.
-
Для простих випадків підійде використання тернарного оператора або шаблонних рядків.
-
Для складних умов краще застосовувати бібліотеки
clsx
абоclassnames
, які забезпечують зручність і читаємість коду.
39. Як писати коментарі в React?
- В React коментарі пишуться так само, як і в JavaScript, але є певні нюанси, коли мова йде про JSX.
- Коментарі в JavaScript (за межами JSX)
// Однорядковий коментар
/*
Багаторядковий коментар
*/
- Коментарі всередині JSX
-
У JSX необхідно використовувати спеціальний синтаксис, оскільки JSX є частиною JavaScript.
-
Коментарі в JSX потрібно писати всередині фігурних дужок
{}
:
function MyComponent() {
return (
<div>
{/_ Це коментар всередині JSX _/}
<h1>Hello, world!</h1>
</div>
);
}
-
Коментарі в JSX повинні бути оточені
{/* коментар */}
, інакше вони викликають помилки. -
Вони можуть бути використані тільки всередині виразів JSX.
- Коментарі в функціях та методах
- Для коментарів всередині функцій або методів можна використовувати стандартні JavaScript коментарі:
function MyComponent() {
// Ось тут ми рендеримо компонент
return <div>Hello, world!</div>;
}
-
У JSX використовуйте
{/* коментар */}
. -
У звичайному JavaScript —
//
для однорядкових і/* ... */
для багаторядкових коментарів.
40. Що таке фрагменти (Fragments) у React?
- Фрагменти в React — це спосіб групувати кілька елементів без додавання зайвих елементів в DOM. Вони дозволяють повернути декілька елементів з компонента без обгортки, такої як
div
, що може допомогти уникнути зайвих елементів, що можуть порушити стилі або структуру документа.
- Без фрагментів (з обгорткою):
function MyComponent() {
return (
<div>
<h1>Title</h1>
<p>Some text</p>
</div>
);
}
- У цьому прикладі повертається один
div
, який обгортаєh1
іp
.
- З фрагментами (без обгортки):
function MyComponent() {
return (
<>
<h1>Title</h1>
<p>Some text</p>
</>
);
}
Тепер h1
і p
рендеряться без додаткового контейнера, що дозволяє зберегти чистоту DOM.
-
Чистий DOM: Можна обходитись без зайвих обгорток у DOM.
-
Зручність для рендерингу кількох елементів: Повернення кількох елементів з одного компонента без необхідності використовувати додаткові елементи.
-
Можна використовувати порожні теги
<>
і</>
, які є скороченням для<React.Fragment></React.Fragment>
. -
Також можна використовувати
React.Fragment
, якщо потрібно додавати ключі (наприклад, при рендерингу списків):
<React.Fragment key={item.id}>
<h1>{item.name}</h1>
<p>{item.description}</p>
</React.Fragment>
-
Коли потрібно рендерити кілька елементів без додаткової обгортки в DOM.
-
Коли зберігаєте структуру компонента без порушення стилів чи верстки.
Фрагменти є дуже корисними для зменшення зайвих елементів у DOM та покращення продуктивності.