Функциональные компоненты в 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 для функций: предотвращает ререндер, если пропсы не изменились (поверхностное сравнение). 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 для мемоизации целого компонента: предотвращает ререндер, если пропсы не изменились. useMemo — хук для мемоизации конкретного значения внутри компонента: кеширует результат функции между рендерами по массиву зависимостей.

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

Самый простой способ — useState с инициализацией от props + useEffect с зависимостью от props для синхронизации. Для редких случаев React recommends: используйте ключ (key) для принудительного пересоздания компонента при изменении входных данных.

Итоги

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

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

IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.

Обсудить проект

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