Skip to content

🎨 Presentational vs. 🧩 Container Components in React


This distinction was popularized by Dan Abramov (one of Redux’s creators) as a way to separate how things look from how things work.

While modern React (hooks, functional components) has made the pattern less mandatory, the mindset is still extremely useful.


Purpose: Focus on UI only — how things look.

  • Concerned with markup and styles.
  • Receive all data via props.
  • Rarely have their own state (unless it’s purely UI state like toggles or form field values).
  • Don’t know where the data comes from.
  • Usually functional components (but could be class-based in older code).
  • Often reusable and easy to test.
const UserCard = ({ name, email, onSelect }) => (
<div className="card" onClick={onSelect}>
<h2>{name}</h2>
<p>{email}</p>
</div>
);

This component doesn’t fetch data, doesn’t manage global state — it just renders UI.


Purpose: Handle logic, data, and behavior — how things work.

  • Manage data fetching.
  • Manage state, reducers, or business logic.
  • Pass data to presentational components.
  • Handle events and transform/update data.
  • Often used to glue UI to external data sources like APIs or global stores.
const UserCardContainer = () => {
const [user, setUser] = useState(null);
useEffect(() => {
fetch("/api/user/1")
.then(res => res.json())
.then(data => setUser(data));
}, []);
if (!user) return <p>Loading...</p>;
return (
<UserCard
name={user.name}
email={user.email}
onSelect={() => console.log("Selected user:", user.id)}
/>
);
};

The container loads data and supplies it to the UI.


AspectPresentationalContainer
Primary concernUILogic/Data
Knows data source?❌ No✔️ Yes
Handles state?RarelyFrequently
Reusable?HighlyLess so
Receives props?✔️✔️ Often passes props
Typical contentsJSX, CSSFetch/axios, state hooks, business logic

While this pattern is still helpful conceptually, hooks blurred the line:

  • A single component often includes UI + logic.
  • Custom hooks now act like the modern equivalent of “containers,” encapsulating logic separately from UI.

For example:

const useUser = () => {
const [user, setUser] = useState(null);
useEffect(() => {
fetch("/api/user/1")
.then(res => res.json())
.then(data => setUser(data));
}, []);
return user;
};
const UserCardContainer = () => {
const user = useUser();
return user ? <UserCard {...user} /> : <p>Loading...</p>;
};

This keeps things clean: logic in hooks, UI in components.


  • Presentational = UI
  • Container = Logic/Data
  • Modern React often merges them, but the separation remains a powerful mental model.
  • Custom hooks now handle most container-like jobs.