Basic Concepts
SOLID Principles in Frontend - WIP
Section titled “SOLID Principles in Frontend - ”SOLID principles are a set of guidelines to consider for maintainable, scalable frontend architecture—they’re not hard rules, and their use should be contextual.
1. Single Responsibility Principle (SRP)
Section titled “1. Single Responsibility Principle (SRP)”- Each component or module should have only one reason to change
- Example: Separating business logic from presentation
// ❌ Bad: Component with multiple responsibilitiesfunction UserProfile({ user }) { const [data, setData] = useState(null);
useEffect(() => { fetchUserData(user.id); }, [user.id]);
return ( <div> <h1>{user.name}</h1> <p>{user.email}</p> <button onClick={() => updateUser(user.id)}>Update</button> </div> );}
// ✅ Good: Separation of responsibilitiesfunction UserProfile({ user }) { const { data, updateUser } = useUserData(user.id);
return ( <div> <h1>{user.name}</h1> <p>{user.email}</p> <button onClick={() => updateUser(user.id)}>Update</button> </div> );}
2. Open/Closed Principle (OCP)
Section titled “2. Open/Closed Principle (OCP)”- Components should be open for extension but closed for modification
- Example: Using composition instead of inheritance
// ❌ Bad: Modifying existing componentfunction Button({ text, onClick }) { return <button onClick={onClick}>{text}</button>;}
// ✅ Good: Extending functionalityfunction PrimaryButton({ text, onClick }) { return <Button text={text} onClick={onClick} className="primary" />;}
3. Liskov Substitution Principle (LSP)
Section titled “3. Liskov Substitution Principle (LSP)”- Derived components should be able to substitute their base components
- Example: Maintaining consistent contracts
// ❌ Bad: Breaking the base component contractfunction SpecialButton({ text, onClick }) { if (!text) return null; // Breaks Button contract return <Button text={text} onClick={onClick} />;}
// ✅ Good: Maintaining the contractfunction SpecialButton({ text, onClick }) { return <Button text={text || 'Default'} onClick={onClick} />;}
4. Interface Segregation Principle (ISP)
Section titled “4. Interface Segregation Principle (ISP)”- Components should not depend on interfaces they don’t use
- Example: Specific props for each use case
// ❌ Bad: Too large interfaceinterface UserProps { name: string; email: string; address: string; phone: string; // ... many more props}
// ✅ Good: Specific interfacesinterface UserBasicInfo { name: string; email: string;}
interface UserContactInfo { phone: string; address: string;}
5. Dependency Inversion Principle (DIP)
Section titled “5. Dependency Inversion Principle (DIP)”- Depend on abstractions, not concrete implementations
- Example: Dependency injection
// ❌ Bad: Direct dependencyfunction UserService() { return { getUsers: () => fetch('/api/users'), };}
// ✅ Good: Inverted dependencyfunction UserService(apiClient) { return { getUsers: () => apiClient.get('/users'), };}