use-effect-event
Version:
Ponyfill of the experimental `React.useEffectEvent` hook
48 lines (33 loc) • 2.81 kB
Markdown
[](https://github.com/sanity-io/use-effect-event/actions/workflows/ci.yml) [](https://www.npmjs.com/package/use-effect-event)
# use-effect-event
> Ponyfill of the experimental `React.useEffectEvent` hook
## Usage
> [!IMPORTANT]
> Make sure you read about [the limitations and understand them](https://react.dev/learn/separating-events-from-effects#limitations-of-effect-events) before you start using this hook, it's not a silver bullet.
This package implements the [same](https://react.dev/learn/separating-events-from-effects#declaring-an-effect-event) [API](https://react.dev/learn/separating-events-from-effects#reading-latest-props-and-state-with-effect-events) as the [experimental](https://19.react.dev/reference/react/experimental_useEffectEvent) `React.useEffectEvent` hook, based on its [implementation in Bluesky](https://github.com/bluesky-social/social-app/blob/ce0bf867ff3b50a495d8db242a7f55371bffeadc/src/lib/hooks/useNonReactiveCallback.ts#L3-L23).
The only difference is that instead of installing an experimental build of React, you can use this package as a ponyfill. Here's an example, [from the official docs](https://react.dev/learn/separating-events-from-effects#reading-latest-props-and-state-with-effect-events), that shows how it can be used to log whenever `url` changes, and still access the latest value of `numberOfItems` without needing to resort to `useRef` proxying:
```tsx
// import {useEffectEvent} from 'react'
import {useEffectEvent} from 'use-effect-event'
function Page({url}) {
const {items} = useContext(ShoppingCartContext)
const numberOfItems = items.length
const onVisit = useEffectEvent((visitedUrl) => {
logVisit(visitedUrl, numberOfItems)
})
useEffect(() => {
onVisit(url)
}, [url])
}
```
## Usage with `eslint-plugin-react-hooks`
In order to use this hook with [`eslint-plugin-react-hooks`](npmjs.com/package/eslint-plugin-react-hooks), install `eslint-plugin-react-hooks@experimental`:
```json
"devDependencies": {
"eslint-plugin-react-hooks": "experimental"
}
```
The experimental version of the `react-hooks` ESLint plugin checks that Effect Events are used according to the [rules](<(https://react.dev/learn/separating-events-from-effects#limitations-of-effect-events)>):
1. `useEffectEvent` functions are not passed between components (`react-hooks/rules-of-hooks`)
2. `useEffectEvent` functions are excluded from the dependency arrays of `useEffect` calls (`react-hooks/exhaustive-deps`)
- this corrects the behavior of the stable version, which erroneously _requires_ that `useEffectEvent` functions are included as effect dependencies.