Skip to content

noComponentHookFactories (JavaScript)

Language JavaScript (and super languages)
biome.json
{
"linter": {
"rules": {
"nursery": {
"noComponentHookFactories": "error"
}
}
}
}

Disallows defining React components or custom hooks inside other functions.

Defining components or hooks inside other functions creates new instances on every call. React treats each new instance as a completely different component, which destroys and recreates the entire component subtree on each render and causes all state to be lost.

A component is defined inside a factory function:

function makeComponent(label) {
function MyComponent() {
return <div>{label}</div>;
}
return MyComponent;
}
code-block.jsx:2:12 lint/nursery/noComponentHookFactories ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

✖ Do not define component MyComponent inside a function.

1 │ function makeComponent(label) {
> 2 │ function MyComponent() {
│ ^^^^^^^^^^^
3 │ return <div>{label}</div>;
4 │ }

ℹ React treats components defined inside functions as completely different on each call, destroying the entire subtree and losing all state. Move it to the module level.

ℹ This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit https://biomejs.dev/linter/#nursery for more information.

A hook is defined inside a factory function:

function makeHook(key) {
function useMyHook() {
return useState(key);
}
return useMyHook;
}
code-block.jsx:2:12 lint/nursery/noComponentHookFactories ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

✖ Do not define hook useMyHook inside a function.

1 │ function makeHook(key) {
> 2 │ function useMyHook() {
│ ^^^^^^^^^
3 │ return useState(key);
4 │ }

ℹ Each call creates a new hook identity, causing React to lose its state across renders. Move it to the module level.

ℹ This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit https://biomejs.dev/linter/#nursery for more information.

Components and hooks defined at the module level:

function MyComponent() {
return <div>Hello</div>;
}
function useMyHook() {
return useState(0);
}

Higher-order components that receive a component as a parameter are allowed:

function withAuth(WrappedComponent) {
function AuthenticatedComponent(props) {
return <WrappedComponent {...props} />;
}
return AuthenticatedComponent;
}