skills/react-best-practices/SKILL.md
React component patterns, hooks, state management, and performance best practices. Use when building or reviewing React components.
npx skillsauth add sabahattinkalkan/antigravity-fullstack-hq react-best-practicesInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
// ✅ Correct
interface UserCardProps {
user: User
onSelect: (id: string) => void
}
export const UserCard = ({ user, onSelect }: UserCardProps) => {
return (
<button onClick={() => onSelect(user.id)} className="...">
{user.name}
</button>
)
}
// ❌ Never use class components
class UserCard extends React.Component {}
// ✅ Use composition
export const Layout = ({ children }: { children: React.ReactNode }) => (
<div className="layout">{children}</div>
)
// ✅ Use context for deep data
const ThemeContext = createContext<Theme | null>(null)
export const useTheme = () => {
const theme = useContext(ThemeContext)
if (!theme) throw new Error('useTheme must be used within ThemeProvider')
return theme
}
// ✅ Extract reusable logic into hooks
const useLocalStorage = <T>(key: string, initial: T) => {
const [value, setValue] = useState<T>(() => {
try {
const item = localStorage.getItem(key)
return item ? JSON.parse(item) : initial
} catch {
return initial
}
})
const set = (val: T) => {
setValue(val)
localStorage.setItem(key, JSON.stringify(val))
}
return [value, set] as const
}
// ✅ Correct — explicit dependencies
useEffect(() => {
fetchUser(userId)
}, [userId])
// ✅ Cleanup when needed
useEffect(() => {
const sub = subscribe(channel)
return () => sub.unsubscribe()
}, [channel])
// ❌ Never ignore the dependency array
useEffect(() => {
fetchUser(userId)
}) // runs on every render
// ✅ Memoize expensive computations
const sorted = useMemo(
() => items.sort((a, b) => a.name.localeCompare(b.name)),
[items]
)
// ✅ Stable callback references
const handleClick = useCallback((id: string) => {
onSelect(id)
}, [onSelect])
// ✅ Prevent unnecessary re-renders
export const HeavyList = memo(({ items }: { items: Item[] }) => (
<ul>{items.map(item => <li key={item.id}>{item.name}</li>)}</ul>
))
// ✅ Lazy load heavy components
const Dashboard = lazy(() => import('./Dashboard'))
export const App = () => (
<Suspense fallback={<Spinner />}>
<Dashboard />
</Suspense>
)
// ✅ Error boundaries for UI errors
export class ErrorBoundary extends React.Component<
{ children: ReactNode; fallback: ReactNode },
{ hasError: boolean }
> {
state = { hasError: false }
static getDerivedStateFromError() { return { hasError: true } }
render() {
return this.state.hasError ? this.props.fallback : this.props.children
}
}
any types on propskey props in listsuseEffectuseEffect for derived state (use useMemo)testing
Generating Excel files with xlsx/exceljs in Node.js. Use when generating .xlsx reports, data exports, dashboards, or spreadsheets from database data.
development
Playwright E2E patterns, Testing Library component tests, test selectors. Use when writing browser tests, component tests, or setting up an E2E testing pipeline for a Next.js or React app.
development
Web design best practices, accessibility, responsive layout, color contrast. Use when auditing a UI for a11y compliance, designing responsive layouts, or establishing design standards across a web app.
tools
TypeScript type system patterns, generics, utility types, and strict mode best practices. Use when writing or reviewing TypeScript code.