React  

Dumb vs Smart components in React

Dumb Components (aka Presentational Components)

  • Focus only on UI: Mostly JSX

  • Stateless: Don’t handle business logic or state (except maybe local UI state)

  • Receive data and callbacks via props

//Button.tsx
function Button({ label, onClick }) {
  return <button onClick={onClick}>{label}</button>;
}

//UserCard.tsx
function UserCard({ name, age }) {
  return (
    <div>
      <h2>{name}</h2>
      <p>Age: {age}</p>
    </div>
  );
}

These components are “dumb” because they don’t manage data; they just render props.

Smart Components (aka Container Components)

  • Focus on how things work (logic, data fetching, state management)

  • Pass data down to dumb components

  • Often stateful

  • Can handle API calls, events, context, etc.

//UserList.tsx
import { useState, useEffect } from "react";
import UserCard from "./UserCard"; // dumb component

function UserList() {
  const [users, setUsers] = useState([]);

  useEffect(() => {
    fetch("/api/users")
      .then(res => res.json())
      .then(data => setUsers(data));
  }, []);

  return (
    <div>
      {users.map(user => (
        <UserCard key={user.id} name={user.name} age={user.age} />
      ))}
    </div>
  );
}

UserList is smart, it fetches data and manages state, but delegates UI to dumb components.

Why even use this pattern?

  • Separates UI from logic, easier to maintain

  • Makes components reusable

  • Easier to test UI without worrying about logic

  • Follows the Single Responsibility Principle

Note. Modern React with hooks sometimes blurs the line, because even “dumb” components can use hooks for local state. The idea is more about responsibility and separation of concerns than strictly whether a component has state.