Suggest an editImprove this articleRefine the answer for “SRP in React components”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)The **Single Responsibility Principle** is the principle of *single responsibility*: "A module should have one, and only one, reason to change" (per Robert Martin, the author of SOLID). In React that "module" is a **component**, and a React component should do only one thing - and do it well. **Key point:** if a component handles logic, appearance, data, and API calls all at once, it violates SRP.Shown above the full answer for quick recall.Answer (EN)Image## What SRP is (in general) **Single Responsibility Principle** is the principle of *single responsibility*. > Definition (per Robert Martin, the author of SOLID): > "A module should have one, and only one, reason to change." In React that "module" is a **component**. If a component does **too much**, then: - it's hard to understand; - it's hard to test; - any change can unpredictably affect other parts of the UI. --- ## SRP in React: a simple definition > **A React component should do only one thing - and do it well.** That is: - One component = one responsibility. - If a component handles logic, appearance, data, and API calls all at once, it violates SRP. --- ## Example of violating SRP (bad code) ```javascript function UserProfile() { const [user, setUser] = useState(null); useEffect(() => { fetch('/api/user') .then(res => res.json()) .then(setUser); }, []); const handleDelete = async () => { await fetch(`/api/user/${user.id}`, { method: 'DELETE' }); setUser(null); }; if (!user) return <div>Loading...</div>; return ( <div> <h1>{user.name}</h1> <button onClick={handleDelete}>Delete user</button> </div> ); } ``` Problems: - The component **fetches data**, - **renders UI**, - **contains business logic** (deletion), - **manages state**. -> Too much responsibility in one place. -> Hard to reuse, test, maintain. --- ## Example with SRP (a correct approach) Let's split the responsibilities: ### 1. The component responsible for data: ```javascript function useUser() { const [user, setUser] = useState(null); useEffect(() => { fetch('/api/user').then(res => res.json()).then(setUser); }, []); const deleteUser = async () => { await fetch(`/api/user/${user.id}`, { method: 'DELETE' }); setUser(null); }; return { user, deleteUser }; } ``` --- ### 2. The component that displays data (UI): ```javascript function UserProfileView({ user, onDelete }) { if (!user) return <div>Loading...</div>; return ( <div> <h1>{user.name}</h1> <button onClick={onDelete}>Delete user</button> </div> ); } ``` --- ### 3. A composition component (a container): ```javascript function UserProfile() { const { user, deleteUser } = useUser(); return <UserProfileView user={user} onDelete={deleteUser} />; } ``` Now: - `useUser` is responsible **for data and business logic**; - `UserProfileView` is responsible **only for the UI**; - `UserProfile` **puts them together**. --- ## Benefits of SRP in React | Benefit | What it provides | |---|---| | Clarity | Each component does one obvious thing | | Reusability | The UI component can be used with different data | | Testability | UI and logic can be tested separately | | Maintainability | Changing logic doesn't break the markup | | Performance | Easier to optimize individual parts | | Extensibility | New features can be added without editing old components | --- ## Typical categories of responsibility in React | Category | Example components | |---|---| | **Presentational (UI)** | buttons, cards, forms, lists, layout | | **Container (logic)** | data loading, API calls, event handling | | **Compositional** | assemble UI components together | | **Hooks / Logic blocks** | contain business logic without UI (`useAuth`, `useCart`, `useUser`) | --- ## Example architecture following SRP ```javascript /components ├── ui/ │ ├── Button.tsx ← UI component │ ├── Card.tsx ← UI component │ └── UserProfileView.tsx← Display ├── containers/ │ └── UserProfile.tsx ← Container /hooks └── useUser.ts ← Data logic ``` -> Each layer does **only its own job**, React components become like "pure interface functions". --- ## When SRP is most often violated Typical situations: 1. A component fetches data and renders it right away; 2. A UI component holds local state unrelated to display; 3. One component manages both layout and logic; 4. Excessive `useEffect` calls inside UI components. --- ## Summary | What SRP means | What it means in React | |---|---| | "One responsibility" | A component solves one task | | Easy to test | Because it does one thing | | Easy to extend | Changing logic doesn't break the UI | | Architecturally clean | UI, logic, and data are separate | | Example | `useUser` (logic) + `UserProfileView` (UI) + `UserProfile` (composition) | --- **In simple terms:** > A React component should be like a clean tool: > **one purpose, one behavior, one place where something can break.**For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.