Skip to main content

What is the "Container-Presentational Pattern"?

The essence of the pattern

The Container-Presentational Pattern splits components into two types:

TypePurpose
ContainerResponsible for logic, data, and state
PresentationalResponsible only for rendering the UI

The idea: "the container thinks, the presentational component shows"


Example

Presentational Component

It receives data via props and simply renders it.

javascript
function UserCard({ name, age }) { return ( <div className="card"> <h2>{name}</h2> <p>Age: {age}</p> </div> ); }

Holds no state Makes no requests Doesn't know where the data comes from → a pure UI component


Container Component

It manages state and logic and passes data down.

javascript
function UserCardContainer() { const [user, setUser] = useState(null); useEffect(() => { fetch('/api/user') .then(res => res.json()) .then(data => setUser(data)); }, []); if (!user) return <p>Loading...</p>; return <UserCard name={user.name} age={user.age} />; }

Fetches data Manages state Triggers side effects Passes data into the presentational component


Why this is needed

ProblemSolution via the pattern
Logic and UI are mixed in one component → hard to readSplit it: one thinks, the other shows
Hard to test and reusePresentational components are easy to test and reuse
Need to render the same UI with different data sourcesYou can use one Presentational with different Containers
A redesign breaks the logicThe UI can be replaced without changing the business logic

Architecturally

javascript
Container (logic) └── Presentational (UI)

For example:

javascript
UserListContainer └── UserList └── UserCard

Typical signs

SignContainerPresentational
Holds stateYesNo
Uses hooks (useState, useEffect)YesRarely
Makes API requestsYesNo
Knows about business logicYesNo
Accepts props for renderingYesYes
Defines markup and stylesNoYes

Example in a modern architecture (React + Redux)

javascript
// Presentational.jsx export function TodoList({ todos, onToggle }) { return ( <ul> {todos.map(todo => ( <li key={todo.id} onClick={() => onToggle(todo.id)} style={{ textDecoration: todo.done ? 'line-through' : 'none' }} > {todo.text} </li> ))} </ul> ); }
javascript
// Container.jsx import { useSelector, useDispatch } from 'react-redux'; import { toggleTodo } from '../store/todoSlice'; import { TodoList } from './Presentational'; export function TodoListContainer() { const todos = useSelector(state => state.todos); const dispatch = useDispatch(); return ( <TodoList todos={todos} onToggle={(id) => dispatch(toggleTodo(id))} /> ); }

In modern React

Although the pattern comes from the era of class components, it is still relevant, just implemented through hooks and composition.

Now the "container" can be:

  • a hook (useUser, useTodos)
  • a wrapper component
  • a context provider

Summary

WhatDescription
IdeaSeparate "logic" from "presentation"
ContainerFetches and processes data
PresentationalRenders the interface
BenefitReusability, readability, testability
Modern equivalentHooks + dumb/UI components

The final formula: Container knows what to show, Presentational knows how to show it.

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.