Функціональні компоненти в React — сучасний стандарт розробки

Автор: IT Sectr Опубліковано: 2026-07-04 Час читання: 9 хв

Functional Component — це спосіб створення компонентів React за допомогою звичайних JavaScript-функцій, який став стандартом після виходу React 16.8 і появи хуків. Функціональні компоненти приймають props і повертають React-елементи, не вимагаючи наслідування від React.Component. За даними React, 2024, 97% нових компонентів в екосистемі React пишуться як функції.

Головне

  • Functional Component — звичайна JavaScript-функція, що приймає props і повертає JSX, без extends Component.
  • Хуки (useState, useEffect, useContext) дають функціональним компонентам повний доступ до стану та життєвого циклу.
  • Читабельність — функціональні компоненти коротші за класові, без конструктора, bind і зайвих методів життєвого циклу.
  • Продуктивність — React оптимізує функціональні компоненти через мемоізацію та ліниву ініціалізацію.
  • Рекомендація React — всі нові проєкти використовувати лише функціональні компоненти з хуками.

Що таке Functional Component?

Functional Component (функціональний компонент) — це React-компонент, визначений як функція, що приймає об'єкт props і повертає React-елемент. До React 16.8 такі компоненти називалися stateless (без стану), тому що вони не могли керувати внутрішнім станом.

З появою хуків у React 16.8 (лютий 2019) функціональні компоненти отримали доступ до стану (useState), побічних ефектів (useEffect), контексту (useContext) та рефів (useRef). Термін «stateless» застарів — сучасні функціональні компоненти повноцінно керують станом.

React офіційно рекомендує функціональні компоненти як основний спосіб створення компонентів. Вся документація на react.dev, приклади, туторіали та нові API (Server Components, Actions) побудовані на функціональному підході. Класові компоненти не видалені, але нові можливості React доступні лише через хуки.

Створення функціонального компонента

Найпростіший функціональний компонент — функція, що повертає JSX. Він приймає props як аргумент, не вимагає конструктора, виклику super або прив'язки this. Props доступні безпосередньо через аргумент функції — жодного this.props.

js
// Functional component without state
function Greeting({ name }) {
  return <h1>Hello, {name}!</h1>;
}

// Arrow function (common variant)
const Greeting = ({ name }) => (
  <h1>Hello, {name}!</h1>
);

Компонент зі станом

Для додавання стану використовуйте useState. Хук повертає кортеж із двох значень: поточний стан і функція-сетер. На відміну від класового this.setState, useState замінює значення цілком, а не зливає з попереднім.

js
import React, { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Increment
      </button>
    </div>
  );
}

Хуки в функціональних компонентах

Хуки — основа сучасного React. Кожен хук вирішує конкретне завдання: useState — стан, useEffect — побічні ефекти, useContext — доступ до контексту, useRef — посилання на DOM-елементи, useCallback та useMemo — мемоізація.

useEffect для побічних ефектів

useEffect замінює componentDidMount, componentDidUpdate та componentWillUnmount одночасно. Перший аргумент — callback з ефектом, другий — масив залежностей. Якщо масив порожній, ефект виконується один раз після монтування. Якщо залежності вказані — при кожній зміні будь-якої з них.

js
import React, { useState, useEffect } from 'react';

function UserData({ userId }) {
  const [user, setUser] = useState(null);

  useEffect(() => {
    let cancelled = false;

    fetch(`/api/users/${userId}`)
      .then(res => res.json())
      .then(data => {
        if (!cancelled) setUser(data);
      });

    // Cleanup - analog of componentWillUnmount
    return () => { cancelled = true; };
  }, [userId]); // Dependency

  return <div>{user?.name}</div>;
}

Кастомні хуки

Головна перевага функціональних компонентів — повторне використання логіки через кастомні хуки. Якщо в класовому компоненті логіка дублювалася між componentDidMount та componentDidUpdate, у функціональному вона виноситься в окрему функцію з префіксом use. Кастомні хуки — основна альтернатива HOC та render props.

Композиція замість наслідування

React рекомендує композицію, а не наслідування для повторного використання коду між компонентами. Функціональні компоненти ідеально підходять для композиції: один компонент може містити кілька інших, передаючи їм props та children.

Паттерн children — коли компонент приймає дочірні елементи через проп children — реалізується природно: function Layout({ children }). Аналог slots із Vue реалізується через іменовані пропси-компоненти: function Page({ header, sidebar, content }).

Наслідування в React практично не використовується. Навіть класові компоненти, які технічно підтримують extends, рідко утворюють ієрархії глибше одного рівня. Функціональні компоненти з композицією повністю покривають потреби у повторному використанні коду без наслідування.

Оптимізація продуктивності

Функціональні компоненти отримують вбудовані механізми оптимізації. React.memo — аналог PureComponent для функцій: запобігає ререндеру, якщо props не змінилися (поверхневе порівняння). useMemo кешує результат обчислень між рендерами.

js
import React, { useMemo } from 'react';

// React.memo - memoize component
const ExpensiveList = React.memo(({ items }) => {
  return <ul>
    {items.map(item =>
      <li key={item.id}>{item.name}</li>
    )}
  </ul>;
});

// useMemo - caching result
function Dashboard({ transactions }) {
  const summary = useMemo(() => {
    return transactions.reduce((acc, t) => acc + t.amount, 0);
  }, [transactions]);

  return <p>Total: {summary}</p>;
}

useCallback мемоізує функції-колбеки, щоб вони не створювалися заново при кожному рендері. Це критично при передачі функцій у дочірні компоненти, обгорнуті в React.memo: без useCallback дочірній компонент буде ререндеритися щоразу, тому що посилання на функцію змінюється.

Порівняння функціональних і класових компонентів

Різниця між підходами виходить за рамки синтаксису. Функціональні компоненти — це замикання: стан та ефекти прив'язані до конкретного рендеру. Класові компоненти — це this: стан завжди береться з this.state, який може бути застарілим на момент виконання асинхронного колбека.

АспектФункціональнийКласовий
СтанuseState (ізольований)this.state + this.setState
ЕфектиuseEffect з залежностямиcomponentDidMount + componentDidUpdate
КонтекстuseContextContext.Consumer або static contextType
ОптимізаціяReact.memo + useMemoPureComponent + shouldComponentUpdate
Логіка повторноКастомні хукиHOC / Render props
thisНемаєbind у конструкторі

Функціональні компоненти дають лінійний потік виконання. У класовому компоненті пов'язана логіка часто розмазана по кількох lifecycle-методах. Наприклад, підписка на WebSocket встановлюється в componentDidMount і видаляється в componentWillUnmount. У функціональному компоненті обидві операції — в одному useEffect з return-функцією очищення.

TypeScript і функціональні компоненти

TypeScript з функціональними компонентами працює природніше, ніж з класами. Типізація пропсів — інтерфейс для аргументу функції. Тип значення, що повертається — JSX.Element або ReactNode. useState автоматично виводить тип із початкового значення.

ts
import React, { useState } from 'react';

interface ButtonProps {
  label: string;
  variant?: 'primary' | 'secondary';
  onClick: () => void;
}

const Button: React.FC<ButtonProps> =
  ({ label, variant = 'primary', onClick }) => (
    <button
      className={`btn btn-${variant}`}
      onClick={onClick}
    >
      {label}
    </button>
  );

Сучасний TypeScript дозволяє типізувати useReducer з дискримінованими union-типами, Generics у кастомних хуках і строгу перевірку children через React.PropsWithChildren. Функціональні компоненти з TypeScript дають повну безпеку типів без додаткових абстракцій.

Часті запитання

Чому React рекомендує функціональні компоненти?

Функціональні компоненти простіші: немає конструктора, bind, this та розрізнених lifecycle-методів. Хуки дозволяють групувати пов'язану логіку. React вкладає ресурси в розвиток хуків, а не класів. Server Components та нові фічі доступні лише у функціях.

Чи можна використовувати setInterval у функціональному компоненті?

Так, через useEffect з таймером всередині та cleanup-функцією для clearInterval. Зверніть увагу на замикання: якщо тікати лічильник, використовуйте функціональну форму setState: setCount(c => c + 1), щоб не залежати від старого значення в замиканні.

Як отримати попередні props у функціональному компоненті?

Використовуйте useRef для зберігання попереднього значення. Оновлюйте ref у useEffect після кожного рендеру. Кастомний хук usePrevious допомагає для чистого порівняння: const prev = usePrevious(value);

Чим React.memo відрізняється від useMemo?

React.memo — HOC для мемоізації цілого компонента: запобігає ререндеру, якщо props не змінилися. useMemo — хук для мемоізації конкретного значення всередині компонента: кешує результат функції між рендерами за масивом залежностей.

Як імітувати getDerivedStateFromProps у функціональному компоненті?

Найпростіший спосіб — useState з ініціалізацією від props + useEffect із залежністю від props для синхронізації. Для рідкісних випадків React рекомендує використовувати ключ (key) для примусового перестворення компонента при зміні вхідних даних.

Підсумки

  • Functional Component — сучасний стандарт React: функція, що приймає props і повертає JSX.
  • Хуки (useState, useEffect) дають функціональним компонентам стан, ефекти та контекст без класів.
  • Композиція через children і кастомні хуки замінює наслідування та HOC-патерни.
  • React.memo та useMemo забезпечують оптимізацію продуктивності функціональних компонентів.
  • TypeScript з функціональними компонентами дає строгу типізацію пропсів та автоматичний вивід типів.
  • useEffect замінює всі lifecycle-методи класових компонентів в одному місці.
  • Кастомні хуки дозволяють виносити та перевикористовувати логіку між компонентами без HOC.

Ми розробимо мобільний застосунок під ключ

IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.

Обговорити проект

Читайте також