How to Create Container and Presentational Components in React
In React, create a
presentational component to focus on UI and display, and a container component to handle data and logic. The container passes data and callbacks as props to the presentational component, keeping concerns separated.Syntax
A presentational component is a simple React function that receives props and returns UI. It does not manage state or logic.
A container component manages state, handles events, and passes data and callbacks to the presentational component.
jsx
function PresentationalComponent({ message, onClick }) { return <button onClick={onClick}>{message}</button>; } function ContainerComponent() { const [count, setCount] = React.useState(0); const handleClick = () => setCount(count + 1); return <PresentationalComponent message={`Clicked ${count} times`} onClick={handleClick} />; }
Output
A button showing text like 'Clicked 0 times' that increments the count on each click.
Example
This example shows a container component managing a click count state and passing it to a presentational button component that displays the count and triggers the increment.
jsx
import React, { useState } from 'react'; function Button({ label, onClick }) { return <button onClick={onClick}>{label}</button>; } function ClickCounter() { const [count, setCount] = useState(0); const increment = () => setCount(count + 1); return <Button label={`Clicked ${count} times`} onClick={increment} />; } export default ClickCounter;
Output
A button labeled 'Clicked 0 times' that updates the label each time it is clicked.
Common Pitfalls
- Putting state and UI logic together in one component can make code hard to maintain.
- Passing too many props from container to presentational can clutter the interface.
- Presentational components should avoid side effects or state to stay reusable.
jsx
/* Wrong: Presentational component managing state */ function Button() { const [count, setCount] = React.useState(0); return <button onClick={() => setCount(count + 1)}>{`Clicked ${count} times`}</button>; } /* Right: Container manages state, presentational only displays */ function Button({ label, onClick }) { return <button onClick={onClick}>{label}</button>; } function Container() { const [count, setCount] = React.useState(0); return <Button label={`Clicked ${count} times`} onClick={() => setCount(count + 1)} />; }
Quick Reference
- Presentational Component: Focus on UI, receive props, no state or side effects.
- Container Component: Manage state, handle logic, pass props to presentational.
- Use this pattern to separate concerns and improve code clarity.
Key Takeaways
Separate UI and logic by using presentational and container components.
Presentational components receive data and callbacks via props and do not manage state.
Container components hold state and pass data to presentational components.
This separation makes components easier to reuse and maintain.
Avoid mixing state and UI in the same component for cleaner code.