Hooks and state
- Do not use
useEffect for simple state updates or derived state.
- Prefer direct calculations,
useMemo, or useCallback when appropriate.
- Keep effects for real side effects: subscriptions, network sync, DOM/browser APIs, timers, external systems.
Avoid unnecessary declarations
- Inline simple logic directly in JSX.
- Do not extract simple handlers, variables, components, or helpers just for naming.
- Declare functions only when logic is complex, reused, or improves readability.
function Counter() {
const [count, setCount] = useState(0);
return <button => setCount(count + 1)}>Count: {count}</button>;
}
Use a named handler only when the body is non-trivial:
function Counter() {
const [count, setCount] = useState(0);
function handleIncrement() {
// complex logic here eg: analytics, validation, side effects, 50 lines of code, etc.
setCount(count + 1);
}
return <button {count}</button>;
}
Keep pure utilities outside components
- Pure functions that do not depend on component scope must live outside the component. This avoids recreating them on every render and keeps components focused.
function Message() {
const [text, setText] = useState("");
return (
<>
<p>{formatDisplayText(text)}</p>
<input value={text} => setText(e.target.value)} />
</>
);
}
function formatDisplayText(text: string) {
return text.toUpperCase();
}
Tailwind classes
- Prefer direct inline Tailwind classes in JSX.
- Do not extract class strings into variables, functions, or helpers.
- For conditional classes, avoid template literals and ternaries; use
cn, clsx, or classnames inline.
<input
className={cn(
"w-full rounded-lg border px-4 py-2 focus:outline-none focus:ring-4",
hasWarning && "border-yellow-500 bg-yellow-50 focus:ring-yellow-200",
hasError && "border-red-500 bg-red-50 focus:ring-red-200",
)}
/>
1---2name: react3description: React code style, conventions, best practices, and patterns for building clean, efficient, and scalable applications. MUST USE for writing or working with any React code, components, hooks, or JSX (.jsx, .tsx files), including editing, reviewing or refactoring.4---56## Hooks and state78- Do not use `useEffect` for simple state updates or derived state.9- Prefer direct calculations, `useMemo`, or `useCallback` when appropriate.10- Keep effects for real side effects: subscriptions, network sync, DOM/browser APIs, timers, external systems.1112## Avoid unnecessary declarations1314- Inline simple logic directly in JSX.15- Do not extract simple handlers, variables, components, or helpers just for naming.16- Declare functions only when logic is complex, reused, or improves readability.1718```tsx19function Counter() {20 const [count, setCount] = useState(0);2122 return <button onClick={() => setCount(count + 1)}>Count: {count}</button>;23}24```2526Use a named handler only when the body is non-trivial:2728```tsx29function Counter() {30 const [count, setCount] = useState(0);3132 function handleIncrement() {33 // complex logic here eg: analytics, validation, side effects, 50 lines of code, etc.34 setCount(count + 1);35 }3637 return <button onClick={handleIncrement}>Count: {count}</button>;38}39```4041## Keep pure utilities outside components4243- Pure functions that do not depend on component scope must live outside the component. This avoids recreating them on every render and keeps components focused.4445```tsx46function Message() {47 const [text, setText] = useState("");4849 return (50 <>51 <p>{formatDisplayText(text)}</p>52 <input value={text} onChange={(e) => setText(e.target.value)} />53 </>54 );55}5657function formatDisplayText(text: string) {58 return text.toUpperCase();59}60```6162## Tailwind classes6364- Prefer direct inline Tailwind classes in JSX.65- Do not extract class strings into variables, functions, or helpers.66- For conditional classes, avoid template literals and ternaries; use `cn`, `clsx`, or `classnames` inline.6768```tsx69<input70 className={cn(71 "w-full rounded-lg border px-4 py-2 focus:outline-none focus:ring-4",72 hasWarning && "border-yellow-500 bg-yellow-50 focus:ring-yellow-200",73 hasError && "border-red-500 bg-red-50 focus:ring-red-200",74 )}75/>76```