logo by @sawaratsuki1004
React
v19.2
Learn
Reference
Community
Blog

Is this page useful?

On this page

  • Overview
  • Rule Details
  • Invalid
  • Valid
  • Troubleshooting
  • I need dynamic component behavior

    react@19.2

  • Overview
  • Hooks
    • useActionState
    • useCallback
    • useContext
    • useDebugValue
    • useDeferredValue
    • useEffect
    • useEffectEvent
    • useId
    • useImperativeHandle
    • useInsertionEffect
    • useLayoutEffect
    • useMemo
    • useOptimistic
    • useReducer
    • useRef
    • useState
    • useSyncExternalStore
    • useTransition
  • المكونات
    • <Fragment> (<>)
    • <Profiler>
    • <StrictMode>
    • <Suspense>
    • <Activity>
    • <ViewTransition> - This feature is available in the latest Canary version of React
  • APIs
    • act
    • addTransitionType - This feature is available in the latest Canary version of React
    • cache
    • cacheSignal
    • captureOwnerStack
    • createContext
    • lazy
    • memo
    • startTransition
    • use
    • experimental_taintObjectReference - This feature is available in the latest Experimental version of React
    • experimental_taintUniqueValue - This feature is available in the latest Experimental version of React
  • react-dom@19.2

  • Hooks
    • useFormStatus
  • المكونات
    • Common (e.g. <div>)
    • <form>
    • <input>
    • <option>
    • <progress>
    • <select>
    • <textarea>
    • <link>
    • <meta>
    • <script>
    • <style>
    • <title>
  • APIs
    • createPortal
    • flushSync
    • preconnect
    • prefetchDNS
    • preinit
    • preinitModule
    • preload
    • preloadModule
  • Client APIs
    • createRoot
    • hydrateRoot
  • Server APIs
    • renderToPipeableStream
    • renderToReadableStream
    • renderToStaticMarkup
    • renderToString
    • resume
    • resumeToPipeableStream
  • Static APIs
    • prerender
    • prerenderToNodeStream
    • resumeAndPrerender
    • resumeAndPrerenderToNodeStream
  • React Compiler

  • Configuration
    • compilationMode
    • gating
    • logger
    • panicThreshold
    • target
  • Directives
    • "use memo"
    • "use no memo"
  • Compiling Libraries
  • React DevTools

  • React Performance tracks
  • eslint-plugin-react-hooks

  • Lints
    • exhaustive-deps
    • rules-of-hooks
    • component-hook-factories
    • config
    • error-boundaries
    • gating
    • globals
    • immutability
    • incompatible-library
    • preserve-manual-memoization
    • purity
    • refs
    • set-state-in-effect
    • set-state-in-render
    • static-components
    • unsupported-syntax
    • use-memo
  • Rules of React

  • Overview
    • Components and Hooks must be pure
    • React calls Components and Hooks
    • Rules of Hooks
  • React Server Components

  • Server Components
  • Server Functions
  • Directives
    • 'use client'
    • 'use server'
  • Legacy APIs

  • Legacy React APIs
    • Children
    • cloneElement
    • Component
    • createElement
    • createRef
    • forwardRef
    • isValidElement
    • PureComponent
API Reference
Lints

component-hook-factories

Validates against higher order functions defining nested components or hooks. Components and hooks should be defined at the module level.

Rule Details

Defining components or hooks inside other functions creates new instances on every call. React treats each as a completely different component, destroying and recreating the entire component tree, losing all state, and causing performance problems.

Invalid

Examples of incorrect code for this rule:

// ❌ Factory function creating components function createComponent(defaultValue) { return function Component() { // ... }; } // ❌ Component defined inside component function Parent() { function Child() { // ... } return <Child />; } // ❌ Hook factory function function createCustomHook(endpoint) { return function useData() { // ... }; }

Valid

Examples of correct code for this rule:

// ✅ Component defined at module level function Component({ defaultValue }) { // ... } // ✅ Custom hook at module level function useData(endpoint) { // ... }

Troubleshooting

I need dynamic component behavior

You might think you need a factory to create customized components:

// ❌ Wrong: Factory pattern function makeButton(color) { return function Button({children}) { return ( <button style={{backgroundColor: color}}> {children} </button> ); }; } const RedButton = makeButton('red'); const BlueButton = makeButton('blue');

Pass JSX as children instead:

// ✅ Better: Pass JSX as children function Button({color, children}) { return ( <button style={{backgroundColor: color}}> {children} </button> ); } function App() { return ( <> <Button color="red">Red</Button> <Button color="blue">Blue</Button> </> ); }

Previousrules-of-hooks
Nextconfig

Copyright © Meta Platforms, Inc
no uwu plz
uwu?
Logo by@sawaratsuki1004
Learn React
Quick Start
Installation
Describing the UI
Adding Interactivity
Managing State
Escape Hatches
API Reference
React APIs
React DOM APIs
Community
Code of Conduct
Meet the Team
Docs Contributors
Acknowledgements
More
Blog
React Native
Privacy
Terms
// ❌ Factory function creating components
function createComponent(defaultValue) {
return function Component() {
// ...
};
}

// ❌ Component defined inside component
function Parent() {
function Child() {
// ...
}

return <Child />;
}

// ❌ Hook factory function
function createCustomHook(endpoint) {
return function useData() {
// ...
};
}
// ✅ Component defined at module level
function Component({ defaultValue }) {
// ...
}

// ✅ Custom hook at module level
function useData(endpoint) {
// ...
}
// ❌ Wrong: Factory pattern
function makeButton(color) {
return function Button({children}) {
return (
<button style={{backgroundColor: color}}>
{children}
</button>
);
};
}

const RedButton = makeButton('red');
const BlueButton = makeButton('blue');
// ✅ Better: Pass JSX as children
function Button({color, children}) {
return (
<button style={{backgroundColor: color}}>
{children}
</button>
);
}

function App() {
return (
<>
<Button color="red">Red</Button>
<Button color="blue">Blue</Button>
</>
);
}