React component patterns, best practices, and architecture guidelines
View on GitHubplugins/aai-stack-react/skills/react-patterns/SKILL.md
February 1, 2026
Select agents to install to:
npx add-skill https://github.com/the-answerai/alphaagent-team/blob/main/plugins/aai-stack-react/skills/react-patterns/SKILL.md -a claude-code --skill react-patternsInstallation paths:
.claude/skills/react-patterns/# React Patterns Skill
Patterns for building well-architected React applications.
## Component Patterns
### Single Responsibility Components
```tsx
// Bad: Doing too much
function UserDashboard() {
const [users, setUsers] = useState([])
const [loading, setLoading] = useState(true)
useEffect(() => {
fetchUsers().then(setUsers).finally(() => setLoading(false))
}, [])
return (
<div>
{loading ? <Spinner /> : users.map(user => (
<div key={user.id}>
<img src={user.avatar} />
<span>{user.name}</span>
<button onClick={() => deleteUser(user.id)}>Delete</button>
</div>
))}
</div>
)
}
// Good: Single responsibility
function UserDashboard() {
const { users, loading } = useUsers()
if (loading) return <Spinner />
return (
<div>
{users.map(user => (
<UserCard key={user.id} user={user} />
))}
</div>
)
}
```
### Container/Presenter Pattern
```tsx
// Container: Handles data and logic
function UserListContainer() {
const { users, loading, error, deleteUser } = useUsers()
return (
<UserList
users={users}
loading={loading}
error={error}
onDelete={deleteUser}
/>
)
}
// Presenter: Handles rendering
interface UserListProps {
users: User[]
loading: boolean
error?: Error
onDelete: (id: string) => void
}
function UserList({ users, loading, error, onDelete }: UserListProps) {
if (loading) return <Spinner />
if (error) return <ErrorMessage error={error} />
return (
<ul>
{users.map(user => (
<UserItem key={user.id} user={user} onDelete={onDelete} />
))}
</ul>
)
}
```
### Compound Components
```tsx
// Compound component pattern for flexible composition
interface TabsContextValue {
activeTab: string
setActiveTab: (tab: string) => void
}
const TabsContext = createContext<TabsContextValue | null>(null)
function Tabs({ children, defaultTab }: { children: ReactNode; defaultTab: stri