Hooks Rules

React hook callback formatting, dependency arrays, and naming conventions

5 rules4 auto-isFixable2 isConfigurable

hook-callback-format

auto-isFixable

React hooks: callback on new line, deps array on separate line

Why: Hooks with callbacks and dependencies are complex; multiline makes them clear
Correct
javascript
useEffect(    () => {        fetchData();    },    [userId],);
Incorrect
javascript
useEffect(() => { fetchData(); }, [userId]);
eslint.config.js
javascript
"code-style/hook-callback-format": "error"

hook-deps-per-line

auto-isFixableisConfigurable

When hook deps exceed threshold, each dependency on its own line

Why: Long dependency arrays are hard to scan and diff

Options

OptionTypeDefaultDescription
maxDepsinteger2Maximum dependencies on single line
eslint.config.js
javascript
"code-style/hook-deps-per-line": ["error", { maxDeps: 2 }]
Correct
javascript
useEffect(    () => {},    [        userId,        token,        refreshToken,    ],);
Incorrect
javascript
useEffect(() => {}, [userId, token, refreshToken, apiUrl]);
eslint.config.js
javascript
"code-style/hook-deps-per-line": "error"

hook-file-naming-convention

report only

Hook files in module subfolders must include the module name

Why: Files like use-create.ts don't indicate which module they belong to
Correct
javascript
hooks/super-admins/use-create-super-admin.ts
Incorrect
javascript
hooks/super-admins/use-create.ts
eslint.config.js
javascript
"code-style/hook-file-naming-convention": "error"

hook-function-naming-convention

auto-isFixable

Hook function name must match camelCase of file name

Why: Files exporting mismatched hook names are misleading
Correct
javascript
// hooks/use-create-super-admin.tsexport const useCreateSuperAdmin = () => { ... };
Incorrect
javascript
// hooks/use-create-super-admin.tsexport const useCreate = () => { ... };
eslint.config.js
javascript
"code-style/hook-function-naming-convention": "error"

use-state-naming-convention

auto-isFixableisConfigurable

Boolean useState variables must start with is/has/with/without prefix

Why: Consistent boolean state naming makes code more predictable

Options

OptionTypeDefaultDescription
booleanPrefixesstring[]["is", "has", "with", "without"]Replace default prefixes
extendBooleanPrefixesstring[][]Add additional prefixes
eslint.config.js
javascript
"code-style/use-state-naming-convention": ["error", { booleanPrefixes: ["is", "has", "with", "without"], extendBooleanPrefixes: [] }]
Correct
javascript
const [isLoading, setIsLoading] = useState(false);const [hasError, setHasError] = useState(false);
Incorrect
javascript
const [loading, setLoading] = useState(false);const [error, setError] = useState(false);
eslint.config.js
javascript
"code-style/use-state-naming-convention": "error"