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

Автор: IT Sectr Публикувано: 2026-07-04 Време за четене: 9 мин

Functional Component — начин за създаване на React компоненти с помощта на обикновени JavaScript функции, който стана стандарт след пускането на React 16.8 и появата на hooks. Функционалните компоненти приемат props и връщат React елементи, без да изискват наследяване от React.Component. Според данни на React, 2024, 97% от новите компоненти в екосистемата на React се пишат като функции.

Основните

  • Functional Component — обикновена JavaScript функция, приемаща props и връщаща JSX, без extends Component.
  • Hooks (useState, useEffect, useContext) дават на функционалните компоненти пълен достъп до състояние и жизнен цикъл.
  • Четимост — функционалните компоненти са по-кратки от класовите, без конструктор, bind и излишни методи на жизнения цикъл.
  • Производителност — React оптимизира функционалните компоненти чрез мемоизация и мързелива инициализация.
  • Препоръка на React — всички нови проекти да използват само функционални компоненти с hooks.

Какво е Functional Component?

Functional Component (функционален компонент) — React компонент, дефиниран като функция, която приема обект props и връща React елемент. Преди React 16.8 такива компоненти се наричаха stateless (без състояние), защото не можеха да управляват вътрешно състояние.

С появата на hooks в React 16.8 (февруари 2019) функционалните компоненти получиха достъп до състояние (useState), странични ефекти (useEffect), контекст (useContext) и референции (useRef). Терминът „stateless" е остарял — модерните функционални компоненти напълно управляват състоянието.

React официално препоръчва функционалните компоненти като основен начин за създаване на компоненти. Цялата документация на react.dev, примерите, уроците и новите API (Server Components, Actions) са изградени върху функционалния подход. Класовите компоненти не са премахнати, но новите възможности на React са достъпни само чрез hooks.

Създаване на функционален компонент

Най-простият функционален компонент — функция, връщаща 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. Hook-ът връща кортеж от две стойности: текущо състояние и функция-setter. За разлика от класовия 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>
  );
}

Hooks във функционалните компоненти

Hooks са основата на модерния React. Всеки hook решава конкретна задача: 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>;
}

Персонализирани hooks

Основното предимство на функционалните компоненти — повторно използване на логика чрез персонализирани hooks. Ако в класовия компонент логиката се дублираше между componentDidMount и componentDidUpdate, във функционалния тя се извлича в отделна функция с префикс use. Персонализираните hooks са основната алтернатива на HOC и render props.

Композиция вместо наследяване

React препоръчва композиция, а не наследяване за повторно използване на код между компоненти. Функционалните компоненти са идеални за композиция: един компонент може да съдържа няколко други, предавайки им props и children.

Моделът children — когато компонент приема наследници чрез prop children — се имплементира естествено: function Layout({ children }). Аналогът на slots от Vue се имплементира чрез именувани props-компоненти: 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 мемоизира callback функции, за да не се създават наново при всяко рендериране. Това е критично при предаване на функции на наследници, обвити в React.memo: без useCallback, наследникът ще се рендерира всеки път, защото референцията към функцията се променя.

Сравнение на функционални и класови компоненти

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

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

Функционалните компоненти осигуряват линеен поток на изпълнение. В класовия компонент свързаната логика често е разпръсната в няколко метода на жизнения цикъл. Например абонаментът за WebSocket се настройва в componentDidMount и се премахва в componentWillUnmount. Във функционалния компонент и двете операции — в един useEffect с функция за почистване.

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

TypeScript с функционални компоненти работи по-естествено, отколкото с класове. Типизиране на props — интерфейс за аргумента на функцията. Типът на връщаната стойност — 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 в персонализирани hooks и строга проверка на children чрез React.PropsWithChildren. Функционалните компоненти с TypeScript дават пълна типова безопасност без допълнителни абстракции.

Често задавани въпроси

Защо React препоръчва функционални компоненти?

Функционалните компоненти са по-прости: няма конструктор, bind, this и разпръснати методи на жизнения цикъл. Hooks позволяват групиране на свързана логика. React инвестира ресурси в развитието на hooks, а не на класове. Server Components и новите функции са достъпни само във функции.

Може ли да се използва setInterval във функционален компонент?

Да, чрез useEffect с таймер вътре и функция за почистване за clearInterval. Обърнете внимание на затварянето: ако тиктакате брояч, използвайте функционалната форма на setState: setCount(c => c + 1), за да не зависите от старата стойност в затварянето.

Как да получа предишни props във функционален компонент?

Използвайте useRef за съхранение на предишната стойност. Актуализирайте ref в useEffect след всяко рендериране. За визуално сравнение помага персонализираният hook usePrevious: const prev = usePrevious(value);

Каква е разликата между React.memo и useMemo?

React.memo — HOC за мемоизация на цял компонент: предотвратява повторно рендериране, ако props не са се променили. useMemo — hook за мемоизация на конкретна стойност вътре в компонента: кешира резултата на функцията между рендериранията въз основа на масив от зависимости.

Как да симулирам getDerivedStateFromProps във функционален компонент?

Най-простият начин — useState с инициализация от props + useEffect със зависимост от props за синхронизиране. За редки случаи React препоръчва: използвайте ключ (key) за принудително пресъздаване на компонента при промяна на входните данни.

Обобщение

  • Functional Component — модерният стандарт на React: функция, приемаща props и връщаща JSX.
  • Hooks (useState, useEffect) дават на функционалните компоненти състояние, ефекти и контекст без класове.
  • Композиция чрез children и персонализирани hooks заменя наследяването и HOC моделите.
  • React.memo и useMemo осигуряват оптимизация на производителността на функционалните компоненти.
  • TypeScript с функционални компоненти дава строго типизиране на props и автоматично извеждане на типове.
  • useEffect заменя всички методи на жизнения цикъл на класовите компоненти на едно място.
  • Персонализирани hooks позволяват извличане и повторно използване на логика между компоненти без HOC.

Ще разработим мобилно приложение под ключ

IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.

Обсъдете проекта

Прочетете също