react/packages/eslint-plugin-react-hooks
Jordan Brown 97cdd5d3c3
[eslint] Do not allow useEffectEvent fns to be called in arbitrary closures (#33544)
Summary:

useEffectEvent is meant to be used specifically in combination with
useEffect, and using
the feature in arbitrary closures can lead to surprising reactivity
semantics. In order to
minimize risk in the experimental rollout, we are going to restrict its
usage to being
called directly inside an effect or another useEffectEvent, effectively
enforcing the function
coloring statically. Without an effect system this is the best we can
do.
2025-07-10 16:51:12 -04:00
..
__tests__ [eslint] Do not allow useEffectEvent fns to be called in arbitrary closures (#33544) 2025-07-10 16:51:12 -04:00
npm Add missing copyright header (#33106) 2025-05-02 16:52:17 -04:00
src [eslint] Do not allow useEffectEvent fns to be called in arbitrary closures (#33544) 2025-07-10 16:51:12 -04:00
babel.config.js feat(eslint-plugin-react-hooks): convert to typescript and package type declarations (#32240) 2025-02-16 14:10:54 -05:00
CHANGELOG.md docs(eslint-plugin-react-hooks): add changelog for 5.1.0 & 5.2.0 (#32536) 2025-03-06 13:58:39 -05:00
index.js feat(eslint-plugin-react-hooks): convert to typescript and package type declarations (#32240) 2025-02-16 14:10:54 -05:00
jest.config.js feat(eslint-plugin-react-hooks): convert to typescript and package type declarations (#32240) 2025-02-16 14:10:54 -05:00
package.json feat(eslint-plugin-react-hooks): merge rule from eslint-plugin-react-compiler into react-hooks plugin (#32416) 2025-03-12 21:43:06 -04:00
README.md docs(eslint-plugin-react-hooks): add 6.0 documentation (#32513) 2025-04-09 12:42:23 -04:00
tsconfig.json feat(eslint-plugin-react-hooks): merge rule from eslint-plugin-react-compiler into react-hooks plugin (#32416) 2025-03-12 21:43:06 -04:00

eslint-plugin-react-hooks

This ESLint plugin enforces the Rules of Hooks.

It is a part of the Hooks API for React.

Installation

Note: If you're using Create React App, please use react-scripts >= 3 instead of adding it directly.

Assuming you already have ESLint installed, run:

# npm
npm install eslint-plugin-react-hooks --save-dev

# yarn
yarn add eslint-plugin-react-hooks --dev

Flat Config (eslint.config.js|ts)

>= 6.0.0

For users of 6.0 and beyond, simply add the recommended config.

import * as reactHooks from 'eslint-plugin-react-hooks';

export default [
  // ...
  reactHooks.configs.recommended,
];

5.2.0

For users of 5.2.0 (the first version with flat config support), add the recommended-latest config.

import * as reactHooks from 'eslint-plugin-react-hooks';

export default [
  // ...
  reactHooks.configs['recommended-latest'],
];

Legacy Config (.eslintrc)

>= 5.2.0

If you are still using ESLint below 9.0.0, you can use recommended-legacy for accessing a legacy version of the recommended config.

{
  "extends": [
    // ...
    "plugin:react-hooks/recommended-legacy"
  ]
}

< 5.2.0

If you're using a version earlier than 5.2.0, the legacy config was simply recommended.

{
  "extends": [
    // ...
    "plugin:react-hooks/recommended"
  ]
}

Custom Configuration

If you want more fine-grained configuration, you can instead add a snippet like this to your ESLint configuration file:

Flat Config (eslint.config.js|ts)

import * as reactHooks from 'eslint-plugin-react-hooks';

export default [
  {
    files: ['**/*.{js,jsx}'],
    plugins: { 'react-hooks': reactHooks },
    // ...
    rules: {
      'react-hooks/rules-of-hooks': 'error',
      'react-hooks/exhaustive-deps': 'warn',
    }
  },
];

Legacy Config (.eslintrc)

{
  "plugins": [
    // ...
    "react-hooks"
  ],
  "rules": {
    // ...
    "react-hooks/rules-of-hooks": "error",
    "react-hooks/exhaustive-deps": "warn"
  }
}

Advanced Configuration

exhaustive-deps can be configured to validate dependencies of custom Hooks with the additionalHooks option. This option accepts a regex to match the names of custom Hooks that have dependencies.

{
  rules: {
    // ...
    "react-hooks/exhaustive-deps": ["warn", {
      additionalHooks: "(useMyCustomHook|useMyOtherCustomHook)"
    }]
  }
}

We suggest to use this option very sparingly, if at all. Generally saying, we recommend most custom Hooks to not use the dependencies argument, and instead provide a higher-level API that is more focused around a specific use case.

Valid and Invalid Examples

Please refer to the Rules of Hooks documentation to learn more about this rule.

License

MIT