Mahamudul Hasan Rubel
HomeAboutProjectsSkillsExperienceBlogPhotosContact
Mahamudul Hasan Rubel

Senior Software Engineer crafting high-performance web applications and SaaS platforms.

Navigation

  • Home
  • About
  • Projects
  • Skills
  • Experience
  • Blog
  • Photos
  • Contact

Get in Touch

Available for senior/lead roles and consulting.

bd.mhrubel@gmail.comHire Me

© 2026 Mahamudul Hasan Rubel. All rights reserved.

Built with using Next.js 16 & Tailwind v4

Back to Blog
ReactNext.jsJune 23, 20264 min read

React Components: How to Choose the Right Boundaries

React components are often split too early or too late. Learn a practical mental model for component architecture that prioritizes performance and readability.

ReactNext.jsFrontend ArchitecturePerformanceWeb DevelopmentTutorial

I remember staring at a 400-line Dashboard.tsx file at 2:00 AM, trying to figure out why a simple toggle caused the entire page to stutter. We had all the logic, styles, and data fetching in one giant component. It was a classic case of ignoring the importance of well-defined boundaries.

When you're starting out, the advice is always "keep your components small." But that’s incomplete. If you break everything into tiny, two-line components, you end up with a "prop-drilling" nightmare that is harder to debug than the original monolith. You need a strategy that considers how React actually works under the hood.

Why Defining React Components Matters

When you define where a component ends and another begins, you’re essentially drawing a line in the sand for React’s reconciliation process. If a component re-renders, everything inside it—all its children—will attempt to re-render by default. This is why understanding React state snapshots is so critical; if you don't keep your state local to the components that actually need it, you’ll trigger unnecessary updates across your entire tree.

I used to think that "reusability" was the only reason to split a component. If I needed a button in two places, I’d pull it out. But that’s a secondary concern. The primary concern is performance and cognitive load.

We once tried to optimize a heavy data table by wrapping every row in a memo component. It actually made the app slower because the overhead of the memoization checks outweighed the cost of the re-render. We had created the wrong boundaries.

A Practical Mental Model for Component Architecture

Instead of arbitrary rules, I use these three heuristics to decide if a piece of UI should be its own component:

  1. State Locality: Does this chunk of UI manage its own state (like a dropdown or a modal)? If yes, it’s a candidate for a separate component. Keeping state local prevents the parent from re-rendering every time the user clicks a button.
  2. Data Fetching Boundaries: If you're using Next.js Server Components, the boundary should be where the data is fetched. By separating the data-fetching logic from the presentation, you can stream parts of the UI while others are still loading.
  3. Cognitive Complexity: If I have to scroll more than three times to read the render function, it’s too big. Period.

The Wrong Turn: Over-Abstraction

A few years ago, I worked on a project where we tried to create a "universal" form component. It had props for every conceivable input type: text, checkbox, select, date, and radio. It became a 600-line monster with so many if/else statements that nobody wanted to touch it.

We had prioritized "DRY" (Don't Repeat Yourself) over "DAMP" (Descriptive and Meaningful Phrases). We should have just written three distinct, simple form components instead of one complex, generic one.

Balancing Performance and Readability

When you look at your component architecture, ask yourself: "If this inner part changes, does the parent need to know?"

If the answer is no, move that part into its own component. This is the secret to keeping your react performance in check. By lifting state out of the parent, you minimize the surface area of your re-renders.

Here’s a quick mental checklist I run through before creating a new file:

  • Is this a visual slice? (e.g., a card, a header)
  • Does it have complex local state? (e.g., an animated sidebar)
  • Is it reused in more than two places? (If yes, it's a good candidate for a shared UI library)

If it fails these, keep it in the parent file. Don't split just to satisfy a "clean code" aesthetic.

FAQ: Common Boundary Questions

How many lines of code should a component be? There is no magic number. I’ve seen 10-line components that were confusing and 150-line components that were perfectly readable. Focus on "Single Responsibility" rather than line counts.

When should I use memo? Only when you have a performance bottleneck. Profile your app with the React DevTools first. If you aren't seeing a performance hit, don't waste time with memo. It adds complexity that you might not need.

Does splitting components hurt bundle size? Generally, no. Modern bundlers are excellent at tree-shaking. Splitting your components actually makes it easier for the compiler to optimize your code.

Final Thoughts

I still struggle with this. Sometimes I split too early, and sometimes I let a file grow until it’s a mess. The key is to treat your component boundaries as living, breathing things. If a component feels like it’s doing too much, break it apart. If you find yourself passing ten props down through four layers of components, you’ve likely drawn your boundaries in the wrong place.

Next time you’re refactoring, try moving the state down rather than moving the logic out. You might find that your code becomes much easier to reason about without adding a single new file.

Back to Blog

Similar Posts

ReactNext.jsJune 23, 20265 min read

React Rendering: How State Updates Trigger DOM Patching in Next.js

React rendering and DOM patching in Next.js can feel like magic. Learn how state updates travel through the component tree to trigger UI changes efficiently.

Read more
ReactNext.js
June 22, 2026
4 min read

React component architecture: Mastering Colocation for Better Maintainability

React component architecture thrives on colocation. Learn why grouping logic, state, and UI by feature beats file-type organization for scalable Next.js apps.

Read more
ReactNext.jsJune 22, 20264 min read

Next.js Streaming SSR: Architecting Progressive Payload Serialization

Next.js Streaming SSR and progressive payload serialization can drastically reduce latency. Learn how to optimize data graphs for faster, smoother delivery.

Read more