Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,21 @@ useEffect(() => {

## Options {/*options*/}

This rule accepts an options object:
You can configure custom effect hooks using shared ESLint settings (available in `eslint-plugin-react-hooks` 6.1.0 and later):

```js
{
"settings": {
"react-hooks": {
"additionalEffectHooks": "(useMyEffect|useCustomEffect)"
}
}
}
```

- `additionalEffectHooks`: Regex pattern matching custom hooks that should be checked for exhaustive dependencies. This configuration is shared across all `react-hooks` rules.

For backward compatibility, this rule also accepts a rule-level option:

```js
{
Expand All @@ -152,4 +166,4 @@ This rule accepts an options object:
}
```

- `additionalHooks`: Regex for hooks that should be checked for exhaustive dependencies
- `additionalHooks`: Regex for hooks that should be checked for exhaustive dependencies. **Note:** If this rule-level option is specified, it takes precedence over the shared `settings` configuration.
Original file line number Diff line number Diff line change
Expand Up @@ -159,3 +159,21 @@ const [permissions, setPermissions] = useState(
userType === 'admin' ? adminPerms : userPerms
);
```

## Options {/*options*/}

You can configure custom effect hooks using shared ESLint settings (available in `eslint-plugin-react-hooks` 6.1.0 and later):

```js
{
"settings": {
"react-hooks": {
"additionalEffectHooks": "(useMyEffect|useCustomEffect)"
}
}
}
```

- `additionalEffectHooks`: Regex pattern matching custom hooks that should be treated as effects. This allows `useEffectEvent` and similar event functions to be called from your custom effect hooks.

This shared configuration is used by both `rules-of-hooks` and `exhaustive-deps` rules, ensuring consistent behavior across all hook-related linting.
6 changes: 4 additions & 2 deletions src/content/reference/react/useEffectEvent.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ Returns an Effect Event function. You can call this function inside `useEffect`,

#### Caveats {/*caveats*/}

- **Only call inside Effects:** Effect Events should only be called within Effects. Define them just before the Effect that uses them. Do not pass them to other components or hooks.
- **Only call inside Effects:** Effect Events should only be called within Effects. Define them just before the Effect that uses them. Do not pass them to other components or hooks. The [`eslint-plugin-react-hooks`](/reference/eslint-plugin-react-hooks) linter (version 6.1.0 or higher) will enforce this restriction to prevent calling Effect Events in the wrong context.
- **Not a dependency shortcut:** Do not use `useEffectEvent` to avoid specifying dependencies in your Effect's dependency array. This can hide bugs and make your code harder to understand. Prefer explicit dependencies or use refs to compare previous values if needed.
- **Use for non-reactive logic:** Only use `useEffectEvent` to extract logic that does not depend on changing values.

Expand Down Expand Up @@ -88,5 +88,7 @@ function Page({ url }) {
}
```

You can pass reactive values like `url` as arguments to the Effect Event. This lets you access the latest values without making your Effect re-run for every change.
In this example, the Effect should re-run after a render when `url` changes (to log the new page visit), but it should **not** re-run when `numberOfItems` changes. By wrapping the logging logic in an Effect Event, `numberOfItems` becomes non-reactive. It's always read from the latest value without triggering the Effect.

You can pass reactive values like `url` as arguments to the Effect Event to keep them reactive while accessing the latest non-reactive values inside the event.