Functional Components in React — The Modern Development Standard

Author: IT Sectr Published: 2026-07-04 Reading time: 9 min

Functional Component — is a way to create React components using regular JavaScript functions, which became the standard after the release of React 16.8 and the introduction of hooks. Functional components accept props and return React elements without requiring inheritance from React.Component. According to React, 2024, 97% of new components in the React ecosystem are written as functions.

Key Takeaways

  • Functional Component — an ordinary JavaScript function accepting props and returning JSX, without extends Component.
  • Hooks (useState, useEffect, useContext) give functional components full access to state and lifecycle.
  • Readability — functional components are shorter than class components, without constructor, bind and extra lifecycle methods.
  • Performance — React optimizes functional components through memoization and lazy initialization.
  • React Recommendation — all new projects should use only functional components with hooks.

What is a Functional Component?

Functional Component is a React component defined as a function that accepts a props object and returns a React element. Before React 16.8, such components were called stateless because they couldn't manage internal state.

With the introduction of hooks in React 16.8 (February 2019), functional components gained access to state (useState), side effects (useEffect), context (useContext) and refs (useRef). The term “stateless” is outdated — modern functional components fully manage state.

React officially recommends functional components as the primary way to create components. All documentation on react.dev, examples, tutorials and new APIs (Server Components, Actions) are built on the functional approach. Class components haven't been removed, but new React features are only available through hooks.

Creating a Functional Component

The simplest functional component is a function that returns JSX. It accepts props as an argument, requires no constructor, super call or this binding. Props are accessible directly through the function argument — no this.props needed.

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

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

Component with State

To add state, use useState. The hook returns a tuple of two values: the current state and a setter function. Unlike class-based this.setState, useState replaces the value entirely rather than merging it with the previous one.

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 in Functional Components

Hooks are the foundation of modern React. Each hook solves a specific task: useState — state management, useEffect — side effects, useContext — context access, useRef — DOM element references, useCallback and useMemo — memoization.

useEffect for Side Effects

useEffect replaces componentDidMount, componentDidUpdate and componentWillUnmount all at once. The first argument is a callback with the effect, the second is a dependency array. If the array is empty, the effect runs once after mounting. If dependencies are specified, it runs whenever any of them changes.

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>;
}

Custom Hooks

The main advantage of functional components is logic reuse through custom hooks. While in a class component logic was duplicated between componentDidMount and componentDidUpdate, in a functional component it is extracted into a separate function with the use prefix. Custom hooks are the primary alternative to HOC and render props.

Composition over Inheritance

React recommends composition rather than inheritance for code reuse between components. Functional components are ideal for composition: one component can contain several others, passing them props and children.

The children pattern — when a component receives child elements through the children prop — is implemented naturally: function Layout({ children }). The Vue slots analog is implemented through named component props: function Page({ header, sidebar, content }).

Inheritance is barely used in React. Even class components, which technically support extends, rarely form hierarchies deeper than one level. Functional components with composition fully cover code reuse needs without inheritance.

Performance Optimization

Functional components come with built-in optimization mechanisms. React.memo — the PureComponent equivalent for functions: prevents re-rendering if props haven't changed (shallow comparison). useMemo caches computation results between renders.

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 memoizes callback functions so they aren't recreated on every render. This is critical when passing functions to child components wrapped in React.memo: without useCallback, the child component will re-render every time because the function reference changes.

Functional vs Class Components

The difference between the approaches goes beyond syntax. Functional components are closures: state and effects are tied to a specific render. Class components use this: state is always retrieved from this.state, which may be outdated by the time an async callback executes.

AspectFunctionalClass
StateuseState (isolated)this.state + this.setState
EffectsuseEffect with dependenciescomponentDidMount + componentDidUpdate
ContextuseContextContext.Consumer or static contextType
OptimizationReact.memo + useMemoPureComponent + shouldComponentUpdate
Logic ReuseCustom hooksHOC / Render props
thisNonebind in constructor

Functional components provide a linear execution flow. In a class component, related logic is often scattered across multiple lifecycle methods. For example, a WebSocket subscription is set up in componentDidMount and torn down in componentWillUnmount. In a functional component, both operations are in a single useEffect with a return cleanup function.

TypeScript and Functional Components

TypeScript works more naturally with functional components than with classes. Props typing — an interface for the function argument. The return type is JSX.Element or ReactNode. useState automatically infers the type from the initial value.

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>
  );

Modern TypeScript allows typing useReducer with discriminated union types, Generics in custom hooks, and strict children validation through React.PropsWithChildren. Functional components with TypeScript provide complete type safety without additional abstractions.

Frequently Asked Questions

Why does React recommend functional components?

Functional components are simpler: no constructor, bind, this or scattered lifecycle methods. Hooks allow grouping related logic. React invests resources in developing hooks, not classes. Server Components and new features are only available in functions.

Can I use setInterval in a functional component?

Yes, through useEffect with a timer inside and a cleanup function for clearInterval. Pay attention to closure: if you're ticking a counter, use the functional form of setState: setCount(c => c + 1) to avoid depending on the old value in the closure.

How do I get previous props in a functional component?

Use useRef to store the previous value. Update the ref in useEffect after each render. A custom hook usePrevious helps for clean comparison: const prev = usePrevious(value);

How is React.memo different from useMemo?

React.memo is an HOC for memoizing an entire component: prevents re-rendering if props haven't changed. useMemo is a hook for memoizing a specific value inside a component: caches a function result between renders by a dependency array.

How to simulate getDerivedStateFromProps in a functional component?

The simplest way is useState with initialization from props + useEffect with a dependency on props for synchronization. For rare cases, React recommends using a key to force component recreation when input data changes.

Summary

  • Functional Component — the modern React standard: a function accepting props and returning JSX.
  • Hooks (useState, useEffect) give functional components state, effects and context without classes.
  • Composition through children and custom hooks replaces inheritance and HOC patterns.
  • React.memo and useMemo provide performance optimization for functional components.
  • TypeScript with functional components provides strict props typing and automatic type inference.
  • useEffect replaces all lifecycle methods of class components in one place.
  • Custom hooks allow extracting and reusing logic between components without HOC.

We will develop a mobile application turnkey

IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.

Discuss the project

Read also