No,Category,Guideline,Description,Do,Don't,Code Good,Code Bad,Severity,Docs URL
1,State,Use useState for local state,Simple component state should use useState hook,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
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
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
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
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
6,Effects,Clean up effects,Return cleanup function for subscriptions timers,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
7,Effects,Specify dependencies correctly,Include all values used inside effect in deps 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
8,Effects,Avoid unnecessary effects,Don't use effects for transforming data or events,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
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
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
11,Rendering,Memoize expensive calculations,Use useMemo for costly computations,useMemo for expensive filtering/sorting,Recalculate every render,"useMemo(() => expensive(), [deps])",const result = expensiveCalc(),Medium,https://react.dev/reference/react/useMemo
12,Rendering,Memoize callbacks passed to children,Use useCallback for functions passed as props,useCallback for handlers passed to memoized children,New function reference every render,"useCallback(() => {}, [deps])",const handler = () => {},Medium,https://react.dev/reference/react/useCallback
13,Rendering,Use React.memo wisely,Wrap components that render often with same props,memo for pure components with stable props,memo everything or nothing,memo(ExpensiveList),memo(SimpleButton),Low,https://react.dev/reference/react/memo
14,Rendering,Avoid inline object/array creation in JSX,Create objects outside render or memoize,Define style objects outside component,Inline objects in props,<div style={styles.container}>,<div style={{ margin: 10 }}>,Medium,
15,Components,Keep components small and focused,Single responsibility for each component,One concern per component,Large multi-purpose components,<UserAvatar /><UserName />,<UserCard /> with 500 lines,Medium,
16,Components,Use composition over inheritance,Compose components using children and props,Use children prop for flexibility,Inheritance hierarchies,<Card>{content}</Card>,class SpecialCard extends Card,Medium,https://react.dev/learn/thinking-in-react
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,
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(...)}</>,<div>{items.map(...)}</div>,Low,https://react.dev/reference/react/Fragment
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,
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,
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,<UserContext.Provider>,<A user={u}><B user={u}><C user={u}>,Medium,https://react.dev/learn/passing-data-deeply-with-context
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,
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
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,
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,
26,Forms,Controlled components for forms,Use state to control form inputs,value + onChange for inputs,Uncontrolled inputs with refs,<input value={val} onChange={setVal}>,<input ref={inputRef}>,Medium,https://react.dev/reference/react-dom/components/input#controlling-an-input-with-a-state-variable
27,Forms,Handle form submission properly,Prevent default and handle in submit handler,onSubmit with preventDefault,onClick on submit button only,<form onSubmit={handleSubmit}>,<button onClick={handleSubmit}>,Medium,
28,Forms,Debounce rapid input changes,Debounce search/filter inputs,useDeferredValue or debounce for search,Filter on every keystroke,useDeferredValue(searchTerm),useEffect filtering on every change,Medium,https://react.dev/reference/react/useDeferredValue
29,Hooks,Follow rules of hooks,Only call hooks at top level and in React functions,Hooks at component top level,Hooks in conditions loops or callbacks,"const [x, setX] = useState()","if (cond) { const [x, setX] = useState() }",High,https://react.dev/reference/rules/rules-of-hooks
30,Hooks,Custom hooks for reusable logic,Extract shared stateful logic to custom hooks,useCustomHook for reusable patterns,Duplicate hook logic across components,const { data } = useFetch(url),Duplicate useEffect/useState in components,Medium,https://react.dev/learn/reusing-logic-with-custom-hooks
31,Hooks,Name custom hooks with use prefix,Custom hooks must start with use,useFetch useForm useAuth,fetchData or getData for hook,function useFetch(url),function fetchData(url),High,
32,Context,Use context for global data,Context for theme auth locale,Context for app-wide state,Context for frequently changing data,<ThemeContext.Provider>,Context for form field values,Medium,https://react.dev/learn/passing-data-deeply-with-context
33,Context,Split contexts by concern,Separate contexts for different domains,ThemeContext + AuthContext,One giant AppContext,<ThemeProvider><AuthProvider>,<AppProvider value={{theme user...}}>,Medium,
34,Context,Memoize context values,Prevent unnecessary re-renders with useMemo,useMemo for context value object,New object reference every render,"value={useMemo(() => ({...}), [])}","value={{ user, theme }}",High,
35,Performance,Use React DevTools Profiler,Profile to identify performance bottlenecks,Profile before optimizing,Optimize without measuring,React DevTools Profiler,Guessing at bottlenecks,Medium,https://react.dev/learn/react-developer-tools
36,Performance,Lazy load components,Use React.lazy for code splitting,lazy() for routes and heavy components,Import everything upfront,const Page = lazy(() => import('./Page')),import Page from './Page',Medium,https://react.dev/reference/react/lazy
37,Performance,Virtualize long lists,Use windowing for lists over 100 items,react-window or react-virtual,Render thousands of DOM nodes,<VirtualizedList items={items}/>,{items.map(i => <Item />)},High,
38,Performance,Batch state updates,React 18 auto-batches but be aware,Let React batch related updates,Manual batching with flushSync,setA(1); setB(2); // batched,flushSync(() => setA(1)),Low,https://react.dev/learn/queueing-a-series-of-state-updates
39,ErrorHandling,Use error boundaries,Catch JavaScript errors in component tree,ErrorBoundary wrapping sections,Let errors crash entire app,<ErrorBoundary><App/></ErrorBoundary>,No error handling,High,https://react.dev/reference/react/Component#catching-rendering-errors-with-an-error-boundary
40,ErrorHandling,Handle async errors,Catch errors in async operations,try/catch in async handlers,Unhandled promise rejections,try { await fetch() } catch(e) {},await fetch() // no catch,High,
41,Testing,Test behavior not implementation,Test what user sees and does,Test renders and interactions,Test internal state or methods,expect(screen.getByText('Hello')),expect(component.state.name),Medium,https://testing-library.com/docs/react-testing-library/intro/
42,Testing,Use testing-library queries,Use accessible queries,getByRole getByLabelText,getByTestId for everything,getByRole('button'),getByTestId('submit-btn'),Medium,https://testing-library.com/docs/queries/about#priority
43,Accessibility,Use semantic HTML,Proper HTML elements for their purpose,button for clicks nav for navigation,div with onClick for buttons,<button onClick={...}>,<div onClick={...}>,High,https://react.dev/reference/react-dom/components#all-html-components
44,Accessibility,Manage focus properly,Handle focus for modals dialogs,Focus trap in modals return focus on close,No focus management,useEffect to focus input,Modal without focus trap,High,
45,Accessibility,Announce dynamic content,Use ARIA live regions for updates,aria-live for dynamic updates,Silent updates to screen readers,"<div aria-live=""polite"">{msg}</div>",<div>{msg}</div>,Medium,
46,Accessibility,Label form controls,Associate labels with inputs,htmlFor matching input id,Placeholder as only label,"<label htmlFor=""email"">Email</label>","<input placeholder=""Email""/>",High,
47,TypeScript,Type component props,Define interfaces for all props,interface Props with all prop types,any or missing types,interface Props { name: string },function Component(props: any),High,
48,TypeScript,Type state properly,Provide types for useState,useState<Type>() for complex state,Inferred any types,useState<User | null>(null),useState(null),Medium,
49,TypeScript,Type event handlers,Use React event types,React.ChangeEvent<HTMLInputElement>,Generic Event type,onChange: React.ChangeEvent<HTMLInputElement>,onChange: Event,Medium,
50,TypeScript,Use generics for reusable components,Generic components for flexible typing,Generic props for list components,Union types for flexibility,<List<T> items={T[]}>,<List items={any[]}>,Medium,
51,Patterns,Container/Presentational split,Separate data logic from UI,Container fetches presentational renders,Mixed data and UI in one,<UserContainer><UserView/></UserContainer>,<User /> with fetch and render,Low,
52,Patterns,Render props for flexibility,Share code via render prop pattern,Render prop for customizable rendering,Duplicate logic across components,<DataFetcher render={data => ...}/>,Copy paste fetch logic,Low,https://react.dev/reference/react/cloneElement#passing-data-with-a-render-prop
53,Patterns,Compound components,Related components sharing state,Tab + TabPanel sharing context,Prop drilling between related,<Tabs><Tab/><TabPanel/></Tabs>,<Tabs tabs={[]} panels={[...]}/>,Low,
54,React19,Use Server Components,Server Components reduce bundle size and improve performance,Server Components for data fetching and static content,Client Components for everything,async function Page() { const data = await fetch() },('use client') everywhere,High,https://react.dev/reference/rsc/server-components
55,React19,Use Actions for forms,Actions handle form submissions with built-in pending states,action={serverAction} on forms,onSubmit with manual state,<form action={submitForm}>,<form onSubmit={async (e) => {...}}>,High,https://react.dev/reference/react-dom/components/form#handle-form-submission-with-a-server-action
56,React19,Use useOptimistic for instant feedback,Show optimistic UI updates before server confirms,useOptimistic for immediate feedback,Wait for server response,const [optimisticLikes setOptimisticLike] = useOptimistic(likes),await updateLikes(); setLikes(newLikes),Medium,https://react.dev/reference/react/useOptimistic
57,React19,Use useFormStatus in forms,Access form pending state in child components,useFormStatus in submit button component,Prop drilling pending state,const { pending } = useFormStatus(),<Button disabled={parentPending}/>,Medium,https://react.dev/reference/react-dom/hooks/useFormStatus
58,React19,Use useActionState for form state,Manage form action results and errors,useActionState for action result state,useState + try/catch pattern,"const [state, formAction] = useActionState(action, initialState)","const [error, setError] = useState()",Medium,https://react.dev/reference/react/useActionState
59,React19,Use use() for promises and context,Read promises and context with use hook,use(promise) for Suspense integration,useEffect + useState for promises,const data = use(dataPromise),useEffect(() => promise.then(setData)),Medium,https://react.dev/reference/react/use
60,React19,Ref as prop in function components,Pass ref directly as prop without forwardRef,ref prop in function components,forwardRef wrapper,function Input({ ref }) { return <input ref={ref}/> },forwardRef((props ref) => ...),Low,https://react.dev/reference/react-dom/components/common#ref-callback
61,React19,Document metadata in components,Render title and meta in component tree,<title> <meta> in components render,React Helmet or manual document.title,return <><title>Page</title><div>...</div></>,useEffect(() => document.title = ...),Low,https://react.dev/reference/react-dom/components/title
62,Animation,Use Framer Motion for complex animations,Framer Motion provides declarative animations with spring physics,Framer Motion for complex orchestrated animations,CSS for complex multi-step animations,"<motion.div animate={{ opacity: 1 scale: 1 }} />",@keyframes with multiple steps,Medium,https://www.framer.com/motion/
63,Animation,AnimatePresence for exit animations,Wrap components that unmount to animate their exit,AnimatePresence around conditional renders,Unmount without exit animation,"<AnimatePresence>{show && <motion.div exit={{ opacity: 0 }} />}</AnimatePresence>",{show && <div className='fade-out'>},High,https://www.framer.com/motion/animate-presence/
64,Animation,Layout animations with layout prop,Use layout prop for automatic layout animations,layout prop for position/size changes,Manual FLIP animations,"<motion.div layout>{expanded && <Content />}</motion.div>",useLayoutEffect with getBoundingClientRect,Medium,https://www.framer.com/motion/layout-animations/
65,Animation,Variants for orchestrated animations,Define animation states as variants for reuse and orchestration,variants with staggerChildren for lists,Inline animate props everywhere,"<motion.ul variants={container}><motion.li variants={item} /></motion.ul>",Each child with separate animate timing,Medium,https://www.framer.com/motion/animation/#variants
66,Animation,useAnimate hook for imperative control,Use useAnimate for programmatic animation sequences,useAnimate for complex sequences and timelines,Multiple refs with manual animation,"const [scope animate] = useAnimate(); await animate(scope.current { x: 100 })",element.style.transform in useEffect,Medium,https://www.framer.com/motion/use-animate/
67,Animation,Respect reduced motion preferences,Check prefers-reduced-motion for accessibility,useReducedMotion hook or media query,Ignore motion preferences,"const prefersReduced = useReducedMotion(); <motion.div animate={prefersReduced ? {} : { scale: 1.1 }} />",<motion.div animate={{ scale: 1.1 }} /> always,High,https://www.framer.com/motion/use-reduced-motion/
68,Animation,whileHover and whileTap gestures,Use gesture props for interactive animations,whileHover whileTap for micro-interactions,onMouseEnter/onMouseLeave with state,"<motion.button whileHover={{ scale: 1.05 }} whileTap={{ scale: 0.95 }} />","<button onMouseEnter={() => setHover(true)} style={{ transform: hover ? 'scale(1.05)' : '' }} />",Low,https://www.framer.com/motion/gestures/
69,Animation,useScroll for scroll-linked animations,Use useScroll hook for scroll-based animations,useScroll with useTransform for parallax,Scroll listeners with state updates,"const { scrollYProgress } = useScroll(); const opacity = useTransform(scrollYProgress [0 1] [0 1])",window.addEventListener('scroll' () => setState(...))",Medium,https://www.framer.com/motion/use-scroll/
70,Animation,useSpring for physics-based animations,React Spring useSpring provides natural physics-based animations with spring dynamics,useSpring for smooth natural-feeling animations,CSS transitions for dynamic values,"const [springs api] = useSpring(() => ({ from: { opacity: 0 } to: { opacity: 1 } }))",transition: opacity 0.3s ease-in-out,Medium,https://www.react-spring.dev/docs/components/use-spring
71,Animation,useTransition for list animations,Animate items entering and leaving lists with useTransition,useTransition for adding/removing list items,Manual key tracking with useState,"const transitions = useTransition(items { keys: item => item.id from: { opacity: 0 } enter: { opacity: 1 } leave: { opacity: 0 } })",{items.map(item => <div key={item.id} className={removing ? 'fade-out' : ''} />)},Medium,https://www.react-spring.dev/docs/components/use-transition
72,Animation,useSprings for multiple animated elements,Animate multiple elements with individual spring configs,useSprings for coordinated multi-element animations,Multiple useSpring calls,"const [springs api] = useSprings(items.length index => ({ x: index * 100 }))",items.map(() => useSpring({...})),Medium,https://www.react-spring.dev/docs/components/use-springs
73,Animation,useTrail for staggered animations,Create staggered animations where each element follows the previous,useTrail for cascading sequential animations,Manual delay calculations per item,"const trail = useTrail(items.length { from: { opacity: 0 y: 20 } to: { opacity: 1 y: 0 } })",items.map((item i) => ({ animationDelay: i * 100 + 'ms' })),Medium,https://www.react-spring.dev/docs/components/use-trail
74,Animation,Controller for imperative spring control,Use Controller class for imperative animation control outside React lifecycle,Controller for complex sequences and external triggers,Refs with manual style manipulation,"const ctrl = new Controller({ opacity: 0 }); ctrl.start({ opacity: 1 }); ctrl.stop()",ref.current.style.opacity = '1'; setTimeout(...),Medium,https://www.react-spring.dev/docs/concepts/controllers-and-springs
75,React-Compiler,Use React Compiler for automatic memoization,React Compiler v1.0 (stable Oct 2025) automatically optimizes re-renders. No manual useMemo/useCallback needed.,Enable React Compiler let it handle memoization,Manual useMemo/useCallback for basic cases,// With React Compiler - no memo needed\nfunction Component({ data }) { return <List items={data} />; },// Old pattern - unnecessary with compiler\nconst memoized = useMemo(() => expensiveCalc(data) [data]);,High,https://react.dev/learn/react-compiler
76,React192,Use Activity for state preservation,<Activity> component in React 19.2 preserves state of hidden components and pre-renders content,Use <Activity mode="hidden"> to preserve unmounted component state,Unmount components that need state preserved,<Activity mode={isVisible ? "visible" : "hidden"}><ExpensiveComponent /></Activity>,{isVisible && <ExpensiveComponent />},Medium,https://react.dev/reference/react/Activity
77,React192,Use useEffectEvent for non-reactive Effect logic,useEffectEvent extracts non-reactive logic from Effects avoiding stale closures,useEffectEvent for event handlers in Effects,Disable lint rules to suppress stale closure warnings,"const onTick = useEffectEvent(() => { console.log(count); }); useEffect(() => { const id = setInterval(onTick 1000); return () => clearInterval(id); } []);","useEffect(() => { const id = setInterval(() => console.log(count) 1000); return () => clearInterval(id); } []); // stale count",High,https://react.dev/reference/react/useEffectEvent
78,React-Compiler,Let Compiler handle memoization,React Compiler automatically determines when to memoize values and callbacks,Write straightforward code Compiler optimizes,Over-optimize with manual memo wrappers,function List({ items }) { return items.map(item => <Item key={item.id} item={item} />); },"const List = memo(({ items }) => { const memoItems = useMemo(() => items.map(...) [items]); });",Medium,https://react.dev/learn/react-compiler
79,React-Compiler,Use eslint-plugin-react-hooks v6,React Compiler comes with enhanced ESLint rules that catch more issues,Upgrade to eslint-plugin-react-hooks@6 with flat config,Use outdated v4 ESLint rules,"// eslint.config.mjs\nimport reactHooks from 'eslint-plugin-react-hooks';\nexport default [reactHooks.configs.recommended];","// .eslintrc.js - outdated format\nmodule.exports = { extends: ['plugin:react-hooks/recommended'] };",Medium,https://react.dev/learn/react-compiler#usage-with-eslint
80,React192,Use React 19.0.1+ for security,Critical vulnerabilities found in RSC Dec 2025. Use 19.0.1+ 19.1.2+ or 19.2.1+,Keep React updated to latest patch,Use vulnerable versions (19.0.0 19.1.0-19.1.1 19.2.0),"""react"": ""^19.2.3""","""react"": ""19.0.0""",Critical,https://react.dev/blog