Skip to main content

What is a "container component"?

Short answer

A container component is a component that:

is responsible for logic, data, and state, but is not responsible for the visual appearance (markup).

It usually:

  • fetches data (from an API, context, store, etc.);
  • manages state (useState, useEffect);
  • passes that data to a presentational (UI) component via props.

The idea behind the split

React components can be roughly divided into two types:

TypeWhat it doesContains
Presentational (UI)Responsible for rendering (markup, styles)JSX
Container (smart)Responsible for logic, data, statehooks, API, handlers

Example 1. Basic example

Presentational component:

javascript
function UserCard({ name, email }) { return ( <div className="user-card"> <h3>{name}</h3> <p>{email}</p> </div> ); }

This component:

  • simply renders data;
  • does not know where it came from.

Container component:

javascript
function UserContainer() { 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} email={user.email} />; }

This component:

  • manages data loading;
  • stores state;
  • passes the result to UserCard.

Example 2. Clean separation of responsibility

javascript
App UserContainer (logic) UserCard (rendering)

UserContainer decides what to show, UserCard decides how it looks.


Example 3. A container can manage several UI components

javascript
function ProductsContainer() { const [products, setProducts] = useState([]); const [filter, setFilter] = useState(""); useEffect(() => { fetch("/api/products") .then(res => res.json()) .then(data => setProducts(data)); }, []); const filtered = products.filter(p => p.name.includes(filter)); return ( <> <SearchBar value={filter} onChange={setFilter} /> <ProductList items={filtered} /> </> ); }

Here:

  • The container manages data and filtering;
  • SearchBar and ProductList simply render the UI.

Advantages of the "Container + Presentational" approach

Separation of concerns - logic separate, UI separate Reusability - UserCard can be used in different places Testability - UI and logic can be tested separately Easier maintenance - changes in logic do not break the markup Improved code readability


Example 4. A generic pattern

javascript
// Container function DataContainer({ render }) { const [data, setData] = useState([]); useEffect(() => { fetch("/api/items") .then(r => r.json()) .then(setData); }, []); return render(data); } // Usage <DataContainer render={(items) => <ItemList items={items} />} />

This uses a render prop, but the idea is the same: the container handles the data, and the child component handles the rendering.


When to use container components

Use one when:

  • the component needs to load data (API, GraphQL, Firebase);
  • you need to store state (useState, useReducer);
  • the component manages interaction logic (for example, filters, sorting, a form);
  • you want to separate the visual layer from the logical one.

When you don't need one

Don't create a container if:

  • the component simply renders UI;
  • it has no logic or state;
  • the data already arrives ready-made through props.

Summary

Component typeMain taskExample
ContainerLogic, state, requests, handlersUserContainer, ProductsContainer
Presentational (UI)Markup and rendering of dataUserCard, ProductList

Main idea:

A container component is a "smart" component that manages logic and data, and delegates the visual part to "dumb" (presentational) components.

Short Answer

Interview ready
Premium

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