React Organizing Components
Table of Contents + −
In the last lesson, React Folder Structure, you set up the project’s folders. Now let’s tidy the components themselves so you don’t end up with huge, do-everything pieces that are hard to read, reuse, and test.
🤔 Why does organizing components matter?
Here’s the pain. As components grow, they turn into tangled monsters that do too much.
- One component fetches data, holds state, handles events, and renders a big chunk of UI.
- It’s hard to read, because you have to understand everything at once.
- It’s hard to reuse, because the display is tangled up with specific logic.
- It’s hard to test, because there’s no clean piece to test on its own.
So organizing components is about keeping each one small with a clear single job.
🧩 Keep components small and focused
The first rule is the most important: each component should do one clear thing.
- If a component is hundreds of lines, it’s probably doing several jobs. Split it.
- A good component has one clear responsibility, like “show a user card” or “handle the login form”.
- Smaller components are easier to name, reuse, and understand at a glance.
So when a component feels too big or hard to name, that’s your signal to break it into smaller pieces.
If it's hard to name, it's doing too much
A quick test: if you can’t give a component a clear, simple name, it’s probably handling too many responsibilities. A component that’s easy to name is usually well-scoped.
🎭 Split presentational and container components
A classic, useful split is separating how it looks from how it works.
- A presentational component just shows UI from its props. No data fetching, no complex logic.
- A container component handles the logic: fetching data, holding state, and passing it down.
- So the container is the brain, and the presentational component is the face.
// presentational: just shows what it's givenfunction UserCard({ name, email }) { return ( <div className="card"> <h3>{name}</h3> <p>{email}</p> </div> );}
// container: handles the logic, then uses the presentational componentfunction UserCardContainer({ userId }) { const { data } = useFetch(`/api/users/${userId}`); if (!data) return <p>Loading...</p>; return <UserCard name={data.name} email={data.email} />;}Read what each does.
UserCardonly takesnameandemailand renders them. So it’s simple and reusable anywhere.UserCardContainerdoes the fetching and loading logic, then hands clean data toUserCard.- So you can reuse
UserCardwith any data source, and test it just by passing props.
Hooks softened this split
With custom hooks, the line is less strict than it used to be, because a component can pull its logic into a hook and stay readable. But the core idea, keep display simple and pull logic out, is still very useful.
📦 Co-locate related files
Keep the files that belong to a component close to it, not scattered across the project.
components/ UserCard/ UserCard.jsx UserCard.module.css UserCard.test.jsxWhy this helps.
- The component, its styles, and its test sit together in one folder.
- To work on
UserCard, you open one folder and everything’s there. - Moving or deleting the component means moving or deleting one folder.
So co-location keeps a component easy to find, change, and remove as a unit.
🏷️ Name and export clearly
Clear names and one component per file keep things predictable.
- Use PascalCase for component names and files, like
UserCard.jsx. - Put one main component per file, named the same as the file.
- Name components for what they are, like
LoginFormorProductList, not vague names likeThingorBox2.
So when you see LoginForm.jsx, you know exactly what’s inside.
⚠️ Common Mistakes
The biggest mistake is the giant component that does everything.
// ❌ one component fetching, holding state, AND rendering a huge UI - hard to managefunction Dashboard() { // 200 lines of fetching, state, handlers, and JSX all mixed together}
// ✅ split into focused piecesfunction Dashboard() { return ( <> <StatsPanel /> <RecentActivity /> <UserList /> </> );}Keep these in mind.
- Don’t let a component grow into a monster. Split it when it does several jobs.
- Don’t tangle display and logic when separating them would make both clearer.
- Don’t use vague names. A component’s name should say what it does.
✅ Best Practices
A few habits for organizing components.
- Keep each component small and focused on one clear job.
- Separate presentational (display) from container (logic) when it makes both cleaner.
- Co-locate a component with its styles and test in one folder.
- Use clear PascalCase names, one main component per file.
Don't over-split either
Small is good, but don’t shatter every few lines into its own component. Split when a component does multiple jobs or a piece is genuinely reused. A sensible middle keeps the code readable without a maze of tiny files.
🧩 What You’ve Learned
- ✅ Keep each component small and focused on one clear responsibility
- ✅ Split presentational components (display from props) from container components (logic and data)
- ✅ Presentational pieces stay reusable and easy to test; containers handle the work
- ✅ Co-locate a component with its styles and test in one folder
- ✅ Use clear PascalCase names, one main component per file
- ✅ Split when a component does too much, but don’t over-split into a maze of tiny files
Check Your Knowledge
Test what you learned. Pick an answer for each question, then click Check.
- 1
What is the main idea behind organizing components?
Why: Small, focused components are easier to read, reuse, test, and fix. When a component does too many jobs, split it into focused pieces.
- 2
What is a presentational component?
Why: A presentational component only renders UI from the props it's given. The logic and data live in a container component that passes clean props to it.
- 3
What does co-locating files mean?
Why: Co-location keeps related files (component, styles, test) in one folder, so the component is easy to find, change, and remove as a unit.
- 4
What's a good sign that a component is doing too much?
Why: If a component is hard to name and runs very long, it's likely handling several responsibilities. That's the signal to split it into focused pieces.
🚀 What’s Next?
Now your components are small, focused, and well-placed. Next we’ll do the same for your custom hooks: where to keep them and how to organize your reusable logic.