See: How to read an often-changing value from useCallback?
Parameters
fn: (args) => result- The callback function to be memoized.
Return Value
(args) => result- A memoized event callback function.
Features
- Memoization: Optimizes performance by memoizing the callback function to avoid unnecessary re-renders.
- Prevents Invocation During Render: Ensures the callback isn't called during rendering, preventing potential issues.
- Error Handling: Throws an error if the callback is mistakenly invoked during rendering.
- Strict Mode Compatibility: Works seamlessly with React's strict mode for better debugging and reliability.
Notes
Avoid using useEventCallback for callback functions that depend on frequently changing state or props.
Usage
import { useEventCallback } from './useEventCallback'
export default function Component() {
const handleClick = useEventCallback(event => {
// Handle the event here
console.log('Clicked', event)
})
return <button onClick={handleClick}>Click me</button>
}
API
function useEventCallback(fn: (args: Args) => R): (args: Args) => R
Custom hook that creates a memoized event callback.
Parameters
| Name | Type | Default value | Description |
|---|---|---|---|
fn | (args: Args) => R | - | The callback function. |
Returns
A memoized event callback function.
Hook
import { useCallback, useRef } from 'react'
import { useIsomorphicLayoutEffect } from '../useIsomorphicLayoutEffect'
/**
* Custom hook that creates a memoized event callback.
* @template Args - An array of argument types for the event callback.
* @template R - The return type of the event callback.
* @param {(...args: Args) => R} fn - The callback function.
* @returns {(...args: Args) => R} A memoized event callback function.
* @public
* @see [Documentation](https://usehooks-ts.com/react-hook/use-event-callback)
* @example
* ```tsx
* const handleClick = useEventCallback((event) => {
* // Handle the event here
* });
* ```
*/
export function useEventCallback<Args extends unknown[], R>(
fn: (...args: Args) => R,
): (...args: Args) => R
export function useEventCallback<Args extends unknown[], R>(
fn: ((...args: Args) => R) | undefined,
): ((...args: Args) => R) | undefined
export function useEventCallback<Args extends unknown[], R>(
fn: ((...args: Args) => R) | undefined,
): ((...args: Args) => R) | undefined {
const ref = useRef<typeof fn>(() => {
throw new Error('Cannot call an event handler while rendering.')
})
useIsomorphicLayoutEffect(() => {
ref.current = fn
}, [fn])
return useCallback((...args: Args) => ref.current?.(...args), [ref]) as (
...args: Args
) => R
}