Interview frequency: …
Short answer
Separate components that fetch data and manage state (Container / Smart) from components that only display data and style the interface (Presentational / Dumb).
Explanation
A smart component fetches data, subscribes to Stores, and handles errors, then passes plain data and event handlers as Props to the presentational component. This makes presentational components easy to test, display in Storybook, and reuse in different contexts.
Code example
// 1. Presentational component (pure and easy to test)
function UserCardView({ name, email, onFollow }: UserCardProps) {
return (
<div className="card">
<h3>{name}</h3>
<p>{email}</p>
<button onClick={onFollow}>Follow</button>
</div>
);
}
// 2. Container component (data fetching and logic)
function UserCardContainer({ userId }: { userId: string }) {
const { data: user } = useQuery({ queryKey: ["user", userId], queryFn: () => fetchUser(userId) });
const handleFollow = () => api.followUser(userId);
if (!user) return <Skeleton />;
return <UserCardView name={user.name} email={user.email} onFollow={handleFollow} />;
}Common mistakes
- Mixing database queries, event handling, and complex styling into one component file of more than 500 lines.