为何大型React无状态组件用内部函数而非拆分独立组件?
Hey there! It makes total sense to be confused by this pattern—when you’re used to the "split everything into small components" best practice, seeing a big component stuffed with helper functions like getButton() can feel counterintuitive. Let’s break down the common reasons teams do this, including performance concerns and practical tradeoffs:
Possible Reasons for This Pattern
1. Historical/Perceived Performance Concerns
Back in the early days of React (before hooks and React.memo were widely adopted), splitting every small piece into a separate functional component could lead to unnecessary re-renders. Each time the parent component re-rendered, all those tiny child components would re-render too—even if their props didn’t change.
For example, if you turned getButton() into a standalone SubmitButton component without memoization, it would re-render every time myComponent re-renders (even if buttonProps stayed the same). Teams sometimes avoided this overhead by keeping logic inline, especially if the component was already performance-sensitive.
That said, with modern React, React.memo makes it easy to memoize small components and prevent unnecessary re-renders. This reason is less valid now, but older codebases might still carry over this habit.
2. "Colocation of Concerns" Preference
Some teams prioritize keeping all logic related to a section of the UI in one place, rather than spreading it across multiple files. For example, getButton(), buttonProps, and getButtonName() are all tightly tied to the button in myComponent—keeping them inline means you don’t have to jump between files to understand how the button works.
This can feel more intuitive for developers who prefer seeing the full context of a UI element without navigating away from the parent component.
3. Low Reusability of the Inline Logic
If the button (or other UI pieces defined via these methods) is only used in this exact component, splitting it into a standalone component might feel like overkill. Creating a new file for a component that’s never reused adds extra boilerplate and file clutter without much benefit.
Teams might choose to keep it inline until there’s a clear need to reuse the logic elsewhere.
4. Rapid Iteration or "Temporary" Code
Sometimes this pattern comes from fast-moving projects where the focus is on shipping features quickly. Developers might throw logic into the parent component first to get things working, with the intention of refactoring into smaller components later.
Unfortunately, "later" never comes as often as we’d like, so this temporary code becomes permanent.
5. Lack of Agreement on Component Splitting Rules
Component splitting is somewhat subjective! What one team considers a "small enough" component to split out, another might think is too trivial. If the team doesn’t have clear guidelines on when to split components, you’ll often see this kind of inline logic.
When You Should Push to Split Components
Even though there are reasons for this pattern, there are definitely cases where splitting is better:
- When the inline logic starts making the parent component too large to navigate (a good rule of thumb: if scrolling through the component takes more than a few seconds, it’s time to split).
- When you need to reuse the UI/logic in another component.
- When you want to test the UI piece independently (testing a standalone
SubmitButtonis easier than testing button logic buried in a big parent component). - When the inline logic grows to include complex state or effects (this applies more as the component evolves beyond simple rendering).
If you do split, remember to use React.memo for child components if you’re worried about re-renders:
const SubmitButton = React.memo(({ buttonProps, buttonName }) => { return <button {...buttonProps}>{buttonName}</button>; });
Wrapping Up
At the end of the day, it’s a tradeoff between performance (less critical now with modern React), maintainability, and team preference. If you’re new to the team, it’s worth asking about their reasoning—they might have context you don’t (like past performance issues or project constraints).
内容的提问来源于stack exchange,提问作者Zoreslav Goral

