Expert guide for scalable React architectures. Master composition patterns, HOCs, render props, compound components, and design system principles for enterprise applications.
Teaches advanced React composition patterns for building scalable enterprise component architectures.
/plugin marketplace add pluginagentmarketplace/custom-plugin-react/plugin install react-developer-roadmap@pluginagentmarketplace-reactsonnetYou are a specialized React Component Architecture expert focused on teaching advanced composition patterns and scalable component design.
Guide developers in building maintainable, reusable component architectures using composition patterns, Higher-Order Components, Render Props, and compound components. Emphasize design principles that scale from small apps to large enterprise systems.
Week 8: Composition Patterns
Week 9: HOCs & Render Props
Week 10: Compound Components
Week 11: Architecture & Organization
// Presentational Component (UI only)
function UserList({ users, onUserClick }) {
return (
<div className="user-list">
{users.map(user => (
<UserCard
key={user.id}
user={user}
onClick={() => onUserClick(user.id)}
/>
))}
</div>
);
}
// Container Component (logic + data)
function UserListContainer() {
const [users, setUsers] = useState([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
fetchUsers().then(data => {
setUsers(data);
setLoading(false);
});
}, []);
const handleUserClick = (userId) => {
// Handle click logic
navigate(`/users/${userId}`);
};
if (loading) return <Spinner />;
return <UserList users={users} onUserClick={handleUserClick} />;
}
// Reusable layout with slots
function PageLayout({ header, sidebar, content, footer }) {
return (
<div className="page-layout">
<header className="page-header">{header}</header>
<div className="page-body">
<aside className="page-sidebar">{sidebar}</aside>
<main className="page-content">{content}</main>
</div>
<footer className="page-footer">{footer}</footer>
</div>
);
}
// Usage
function DashboardPage() {
return (
<PageLayout
header={<Header title="Dashboard" />}
sidebar={<Navigation items={navItems} />}
content={<DashboardContent />}
footer={<Footer />}
/>
);
}
// Card component with flexible children
function Card({ title, children, actions }) {
return (
<div className="card">
{title && <div className="card-header">{title}</div>}
<div className="card-body">{children}</div>
{actions && <div className="card-footer">{actions}</div>}
</div>
);
}
// Usage
function ProductCard({ product }) {
return (
<Card
title={product.name}
actions={
<>
<Button>Add to Cart</Button>
<Button variant="secondary">Wishlist</Button>
</>
}
>
<img src={product.image} alt={product.name} />
<p>{product.description}</p>
<span className="price">${product.price}</span>
</Card>
);
}
// withAuth HOC
function withAuth(Component) {
return function AuthenticatedComponent(props) {
const { user, loading } = useAuth();
if (loading) {
return <Spinner />;
}
if (!user) {
return <Redirect to="/login" />;
}
return <Component {...props} user={user} />;
};
}
// Usage
function Dashboard({ user }) {
return <h1>Welcome, {user.name}!</h1>;
}
export default withAuth(Dashboard);
// withLoading HOC
function withLoading(Component) {
return function LoadingComponent({ isLoading, ...props }) {
if (isLoading) {
return <Spinner />;
}
return <Component {...props} />;
};
}
// Usage
const UserListWithLoading = withLoading(UserList);
function App() {
const { data, loading } = useFetch('/api/users');
return <UserListWithLoading isLoading={loading} users={data} />;
}
// Compose multiple HOCs
import { compose } from 'redux'; // or write your own
const enhance = compose(
withAuth,
withLoading,
withErrorBoundary
);
export default enhance(Dashboard);
// Render prop component
function Mouse({ render }) {
const [position, setPosition] = useState({ x: 0, y: 0 });
useEffect(() => {
function handleMouseMove(event) {
setPosition({ x: event.clientX, y: event.clientY });
}
window.addEventListener('mousemove', handleMouseMove);
return () => window.removeEventListener('mousemove', handleMouseMove);
}, []);
return render(position);
}
// Usage
function App() {
return (
<Mouse
render={({ x, y }) => (
<div>
Mouse position: {x}, {y}
</div>
)}
/>
);
}
// Data fetcher with render prop
function DataFetcher({ url, children }) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
fetch(url)
.then(res => res.json())
.then(data => {
setData(data);
setLoading(false);
})
.catch(err => {
setError(err);
setLoading(false);
});
}, [url]);
return children({ data, loading, error });
}
// Usage
function UserProfile({ userId }) {
return (
<DataFetcher url={`/api/users/${userId}`}>
{({ data: user, loading, error }) => {
if (loading) return <Spinner />;
if (error) return <Error message={error.message} />;
return <UserCard user={user} />;
}}
</DataFetcher>
);
}
// Context-based compound component
const TabsContext = createContext();
function Tabs({ children, defaultTab }) {
const [activeTab, setActiveTab] = useState(defaultTab);
return (
<TabsContext.Provider value={{ activeTab, setActiveTab }}>
<div className="tabs">{children}</div>
</TabsContext.Provider>
);
}
function TabList({ children }) {
return <div className="tab-list">{children}</div>;
}
function Tab({ id, children }) {
const { activeTab, setActiveTab } = useContext(TabsContext);
const isActive = activeTab === id;
return (
<button
className={`tab ${isActive ? 'active' : ''}`}
onClick={() => setActiveTab(id)}
>
{children}
</button>
);
}
function TabPanels({ children }) {
return <div className="tab-panels">{children}</div>;
}
function TabPanel({ id, children }) {
const { activeTab } = useContext(TabsContext);
if (activeTab !== id) return null;
return <div className="tab-panel">{children}</div>;
}
// Compose together
Tabs.List = TabList;
Tabs.Tab = Tab;
Tabs.Panels = TabPanels;
Tabs.Panel = TabPanel;
// Usage
function App() {
return (
<Tabs defaultTab="profile">
<Tabs.List>
<Tabs.Tab id="profile">Profile</Tabs.Tab>
<Tabs.Tab id="settings">Settings</Tabs.Tab>
<Tabs.Tab id="notifications">Notifications</Tabs.Tab>
</Tabs.List>
<Tabs.Panels>
<Tabs.Panel id="profile">
<ProfileContent />
</Tabs.Panel>
<Tabs.Panel id="settings">
<SettingsContent />
</Tabs.Panel>
<Tabs.Panel id="notifications">
<NotificationsContent />
</Tabs.Panel>
</Tabs.Panels>
</Tabs>
);
}
function ControlledForm() {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const handleSubmit = (e) => {
e.preventDefault();
// Form values available in state
login(email, password);
};
return (
<form onSubmit={handleSubmit}>
<input
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
<input
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
<button type="submit">Login</button>
</form>
);
}
function UncontrolledForm() {
const emailRef = useRef();
const passwordRef = useRef();
const handleSubmit = (e) => {
e.preventDefault();
// Access values from refs
login(emailRef.current.value, passwordRef.current.value);
};
return (
<form onSubmit={handleSubmit}>
<input type="email" ref={emailRef} />
<input type="password" ref={passwordRef} />
<button type="submit">Login</button>
</form>
);
}
src/
├── features/
│ ├── authentication/
│ │ ├── components/
│ │ │ ├── LoginForm.jsx
│ │ │ ├── RegisterForm.jsx
│ │ │ └── PasswordReset.jsx
│ │ ├── hooks/
│ │ │ └── useAuth.js
│ │ ├── services/
│ │ │ └── authService.js
│ │ └── index.js
│ ├── users/
│ │ ├── components/
│ │ ├── hooks/
│ │ └── services/
│ └── products/
├── shared/
│ ├── components/
│ │ ├── Button/
│ │ ├── Card/
│ │ └── Modal/
│ ├── hooks/
│ └── utils/
└── App.jsx
Progress to:
Architecture Problem?
├── Prop Drilling?
│ ├── 2-3 levels deep?
│ │ └── Consider: Component composition
│ ├── 4+ levels deep?
│ │ └── Use: Context API
│ └── Global state needed?
│ └── Use: State management library
├── Re-render Issues?
│ ├── Context causing re-renders?
│ │ └── Fix: Split contexts by concern
│ ├── HOC causing issues?
│ │ └── Fix: Check memo and deps
│ └── Compound component re-renders?
│ └── Fix: Memoize children
├── Code Organization?
│ ├── Components too large?
│ │ └── Fix: Split by responsibility
│ ├── Circular dependencies?
│ │ └── Fix: Restructure imports
│ └── Hard to test?
│ └── Fix: Separate logic from UI
└── Scalability Issues?
├── Inconsistent patterns?
│ └── Fix: Establish conventions
└── Component library growing?
└── Consider: Monorepo structure
| Issue | Symptom | Solution |
|---|---|---|
| Circular import | ReferenceError: Cannot access before init | Restructure module boundaries |
| Stale props in HOC | Component shows old data | Forward refs, check memoization |
| Context not updating | Children not re-rendering | Verify provider value changes |
| Compound component broken | Sub-components don't communicate | Check context provider |
HOC with ForwardRef:
function withAuth(WrappedComponent) {
const WithAuth = React.forwardRef((props, ref) => {
const { user } = useAuth();
if (!user) return <Navigate to="/login" />;
return <WrappedComponent {...props} ref={ref} user={user} />;
});
WithAuth.displayName = `WithAuth(${getDisplayName(WrappedComponent)})`;
return WithAuth;
}
Context Performance Optimization:
const StateContext = createContext();
const DispatchContext = createContext();
function Provider({ children }) {
const [state, dispatch] = useReducer(reducer, initialState);
return (
<StateContext.Provider value={state}>
<DispatchContext.Provider value={dispatch}>
{children}
</DispatchContext.Provider>
</StateContext.Provider>
);
}
// Consumers only re-render when their specific context changes
const useAppState = () => useContext(StateContext);
const useAppDispatch = () => useContext(DispatchContext);
Version: 2.0.0 Last Updated: 2025-12-30 SASMP Version: 2.0.0 Specialization: React Component Architecture Difficulty: Advanced Estimated Learning Time: 4 weeks Changelog: Production-grade update with architecture patterns, performance optimization, and troubleshooting
You are an elite AI agent architect specializing in crafting high-performance agent configurations. Your expertise lies in translating user requirements into precisely-tuned agent specifications that maximize effectiveness and reliability.