No,Category,Guideline,Description,Do,Don't,Code Good,Code Bad,Severity,Docs URL,Applies To,Status,Verified At 1,State,Use useState for local state,Simple component state should use useState hook in current React apps.,useState for form inputs toggles counters,Class components this.state,"const [count, setCount] = useState(0)",this.state = { count: 0 },Medium,https://react.dev/reference/react/useState,react 19.2.x,active,2026-08-13 2,State,Lift state up when needed,Share state between siblings by lifting to parent,Lift shared state to common ancestor,Prop drilling through many levels,Parent holds state passes down,Deep prop chains,Medium,https://react.dev/learn/sharing-state-between-components,react 19.2.x,active,2026-08-13 3,State,Use useReducer for complex state,Complex state logic benefits from reducer pattern,useReducer for state with multiple sub-values,Multiple useState for related values,useReducer with action types,5+ useState calls that update together,Medium,https://react.dev/reference/react/useReducer,react 19.2.x,active,2026-08-13 4,State,Avoid unnecessary state,Derive values from existing state when possible,Compute derived values in render,Store derivable values in state,const total = items.reduce(...),"const [total, setTotal] = useState(0)",High,https://react.dev/learn/choosing-the-state-structure,react 19.2.x,active,2026-08-13 5,State,Initialize state lazily,Use function form for expensive initial state,useState(() => computeExpensive()),useState(computeExpensive()),useState(() => JSON.parse(data)),useState(JSON.parse(data)),Medium,https://react.dev/reference/react/useState#avoiding-recreating-the-initial-state,react 19.2.x,active,2026-08-13 6,Effects,Clean up effects,Return cleanup for subscriptions and timers so effects stay predictable.,Return cleanup function in useEffect,No cleanup for subscriptions,useEffect(() => { sub(); return unsub; }),useEffect(() => { subscribe(); }),High,https://react.dev/reference/react/useEffect#connecting-to-an-external-system,react 19.2.x,active,2026-08-13 7,Effects,Specify dependencies correctly,Include every reactive value used inside an Effect dependency array.,All referenced values in dependency array,Empty deps with external references,[value] when using value in effect,[] when using props/state in effect,High,https://react.dev/reference/react/useEffect#specifying-reactive-dependencies,react 19.2.x,active,2026-08-13 8,Effects,Avoid unnecessary effects,Avoid Effects for derived data or event handling.,Transform data during render handle events directly,useEffect for derived state or event handling,const filtered = items.filter(...),useEffect(() => setFiltered(items.filter(...))),High,https://react.dev/learn/you-might-not-need-an-effect,react 19.2.x,active,2026-08-13 9,Effects,Use refs for non-reactive values,Store values that don't trigger re-renders in refs,useRef for interval IDs DOM elements,useState for values that don't need render,const intervalRef = useRef(null),"const [intervalId, setIntervalId] = useState()",Medium,https://react.dev/reference/react/useRef,react 19.2.x,active,2026-08-13 10,Rendering,Use keys properly,Stable unique keys for list items,Use stable IDs as keys,Array index as key for dynamic lists,key={item.id},key={index},High,https://react.dev/learn/rendering-lists#keeping-list-items-in-order-with-key,react 19.2.x,active,2026-08-13 11,Rendering,Memoize expensive calculations,Prefer compiler-first memoization; use useMemo only for measured hotspots or explicit cache boundaries.,Use useMemo for expensive computations when profiling shows a real bottleneck,Use useMemo everywhere by default,"useMemo(() => expensive(), [deps])",const result = expensiveCalc(),Medium,https://react.dev/reference/react/useMemo,react 19.2.x,active,2026-08-13 12,Rendering,Memoize callbacks passed to children,Use useCallback only when callback identity matters for measured child renders.,Use useCallback for handlers passed to memoized children when identity is a bottleneck,Wrap every function in useCallback by default,"useCallback(() => {}, [deps])",const handler = () => {},Medium,https://react.dev/reference/react/useCallback,react 19.2.x,active,2026-08-13 13,Rendering,Use React.memo wisely,"Keep React.memo as a measured optimization, not a blanket default.",Use React.memo for pure components with stable props and real render cost,Memoize every component or use it as a guess,memo(ExpensiveList),memo(SimpleButton),Low,https://react.dev/reference/react/memo,react 19.2.x,active,2026-08-13 14,Rendering,Avoid inline object/array creation in JSX,Create objects outside render or memoize,Define style objects outside component,Inline objects in props,
,
,Medium,,react 19.2.x,active,2026-08-13 15,Components,Keep components small and focused,Single responsibility for each component,One concern per component,Large multi-purpose components,, with 500 lines,Medium,,react 19.2.x,active,2026-08-13 16,Components,Use composition over inheritance,Compose components using children and props,Use children prop for flexibility,Inheritance hierarchies,{content},class SpecialCard extends Card,Medium,https://react.dev/learn/thinking-in-react,react 19.2.x,active,2026-08-13 17,Components,Colocate related code,Keep related components and hooks together,Related files in same directory,Flat structure with many files,components/User/UserCard.tsx,components/UserCard.tsx + hooks/useUser.ts,Low,,react 19.2.x,active,2026-08-13 18,Components,Use fragments to avoid extra DOM,Fragment or <> for multiple elements without wrapper,<> for grouping without DOM node,Extra div wrappers,<>{items.map(...)},
{items.map(...)}
,Low,https://react.dev/reference/react/Fragment,react 19.2.x,active,2026-08-13 19,Props,Destructure props,Destructure props for cleaner component code,Destructure in function signature,props.name props.value throughout,"function User({ name, age })",function User(props),Low,,react 19.2.x,active,2026-08-13 20,Props,Provide default props values,Use default parameters or defaultProps,Default values in destructuring,Undefined checks throughout,function Button({ size = 'md' }),if (size === undefined) size = 'md',Low,,react 19.2.x,active,2026-08-13 21,Props,Avoid prop drilling,Use context or composition for deeply nested data,Context for global data composition for UI,Passing props through 5+ levels,,,Medium,https://react.dev/learn/passing-data-deeply-with-context,react 19.2.x,active,2026-08-13 22,Props,Validate props with TypeScript,Use TypeScript interfaces for prop types,interface Props { name: string },PropTypes or no validation,interface ButtonProps { onClick: () => void },Button.propTypes = {},Medium,,react 19.2.x,active,2026-08-13 23,Events,Use synthetic events correctly,React normalizes events across browsers,e.preventDefault() e.stopPropagation(),Access native event unnecessarily,onClick={(e) => e.preventDefault()},onClick={(e) => e.nativeEvent.preventDefault()},Low,https://react.dev/reference/react-dom/components/common#react-event-object,react 19.2.x,active,2026-08-13 24,Events,Avoid binding in render,Use arrow functions in class or hooks,Arrow functions in functional components,bind in render or constructor,const handleClick = () => {},this.handleClick.bind(this),Medium,,react 19.2.x,active,2026-08-13 25,Events,Pass event handlers not call results,Pass function reference not invocation,onClick={handleClick},onClick={handleClick()} causing immediate call,onClick={handleClick},onClick={handleClick()},High,https://react.dev/learn/responding-to-events,react 19.2.x,active,2026-08-13 26,Forms,Controlled components for forms,Use state to control form inputs,value + onChange for inputs,Uncontrolled inputs with refs,,,Medium,https://react.dev/reference/react-dom/components/input#controlling-an-input-with-a-state-variable,react 19.2.x,active,2026-08-13 27,Forms,Handle form submission properly,Prevent default and handle in submit handler,onSubmit with preventDefault,onClick on submit button only,
,
},function Form(){ const { pending } = useFormStatus(); return
...
},High,https://react.dev/reference/react-dom/hooks/useFormStatus,react 19.2.x,active,2026-09-21 64,Hooks,Use use() with stable promises or context,Reads context or suspends on a promise until it resolves.,Pass a cached or otherwise stable promise to use(),Create a new promise during render,const data = use(dataPromise),const data = use(fetch('/api/data')),Medium,https://react.dev/reference/react/use,react 19.2.x,active,2026-09-21 65,Concurrency,Call useOptimistic updates inside an Action,Temporarily shows the expected state while an Action is pending.,Call the optimistic setter inside startTransition or an action prop,Call the optimistic setter outside an Action,startTransition(async () => { addOptimistic(item); await save(item); }),addOptimistic(item); await save(item),Medium,https://react.dev/reference/react/useOptimistic,react 19.2.x,active,2026-09-21 66,Forms,Use form actions for Action-based submissions,Passing a function to action runs it in a Transition; Server Functions can progressively enhance forms.,Use a Server Function with useActionState when submission must work before hydration,Claim progressive enhancement for a client-only action,
...
,
...
// requires JavaScript,Medium,https://react.dev/reference/react-dom/components/form,react 19.2.x,active,2026-09-21