# How to Use React useCallback with a Parameter to Optimize Performance

> Learn how to effectively use React useCallback with a parameter to optimize component performance. Keep your callback function references stable across renders by defining arguments and providing values at invocation time.

- Repository: [Meta/react](https://github.com/facebook/react)
- Tags: getting-started
- Published: 2026-02-16

---

**Use `useCallback` to memoize callback functions that accept parameters by defining arguments in the function signature while supplying values at invocation time, keeping the function reference stable across renders when dependencies remain unchanged.**

The `useCallback` Hook is essential for performance optimization in React applications, particularly when passing functions to memoized child components. According to the facebook/react source code, this Hook leverages the reconciler's internal memoization mechanism to preserve function references. Understanding how to effectively use **react usecallback with a parameter** allows developers to maintain referential stability while handling dynamic data.

## How useCallback Works in React's Source

### Hook Dispatcher Entry Point

In [`packages/react/src/ReactHooks.js`](https://github.com/facebook/react/blob/main/packages/react/src/ReactHooks.js), the `useCallback` Hook serves as the public API entry point that forwards to the current renderer's implementation:

```javascript
export function useCallback<T>(callback: T, deps: Array<mixed> | void | null): T {
  return dispatcher.useCallback(callback, deps);
}

```

### Reconciler Memoization Logic

The actual memoization occurs in [`packages/react-reconciler/src/ReactFiberHooks.js`](https://github.com/facebook/react/blob/main/packages/react-reconciler/src/ReactFiberHooks.js). During the initial render, `mountCallback` stores the callback alongside its dependency array in a Hook node. Subsequent renders invoke `updateCallback`, which compares the new dependencies against the previous list using `areHookInputsEqual`. If the arrays are shallowly equal, React returns the previously stored function reference unchanged; otherwise, it creates a new memoized wrapper.

## Implementing useCallback with Parameters

### The Parameter Pattern

When using react usecallback with a parameter, define the parameter in the callback's signature at definition time. The arguments are supplied later when the component or event handler invokes the function:

```tsx
const handleClick = React.useCallback(
  (id: number) => {
    onSelect(id);
  },
  [onSelect]
);

```

The callback reference (`handleClick`) stays stable across renders as long as `onSelect` does not change, while the `id` parameter is supplied at call-time.

### Referential Stability Benefits

This pattern ensures the function reference remains identical across renders when dependencies are unchanged. Child components receiving this callback as a prop avoid unnecessary re-renders because their reference equality checks remain stable. Additionally, any `useEffect` that lists the callback in its dependency array will not re-run due to reference changes.

## Practical Code Examples

### Counter with Dynamic Increments

This example demonstrates a stable incrementer that receives variable amounts:

```tsx
import React from 'react';

function Counter() {
  const [count, setCount] = React.useState(0);

  const increment = React.useCallback((delta: number) => {
    setCount(prev => prev + delta);
  }, []);

  return (
    <>
      <p>Count: {count}</p>
      <button onClick={() => increment(1)}>+1</button>
      <button onClick={() => increment(5)}>+5</button>
    </>
  );
}

```

The `increment` function is created once during the initial render. Clicking different buttons merely invokes the same stable reference with different arguments.

### Optimized List Rendering

When passing callbacks to memoized children, parameterization prevents unnecessary re-renders:

```tsx
const List = React.memo(function List({items, onSelect}) {
  return (
    <ul>
      {items.map(item => (
        <ListItem key={item.id} item={item} onSelect={onSelect} />
      ))}
    </ul>
  );
});

function Parent() {
  const [selected, setSelected] = React.useState(null);
  const items = React.useMemo(() => generateItems(), []);

  const handleSelect = React.useCallback(id => {
    setSelected(id);
  }, []);

  return (
    <>
      <List items={items} onSelect={handleSelect} />
      <p>Selected ID: {selected}</p>
    </>
  );
}

```

`List` only re-renders when `items` or `handleSelect` change. Because `handleSelect` is memoized, child `ListItem` components receive a stable prop reference and avoid unnecessary re-renders even when the parent updates for other reasons.

### Stable Callbacks with Mutable Refs

Combine `useCallback` with `useRef` to read mutable values without breaking referential stability:

```tsx
function SearchBox({onSearch}) {
  const queryRef = React.useRef('');

  const submit = React.useCallback(() => {
    onSearch(queryRef.current);
  }, [onSearch]);

  return (
    <form onSubmit={e => { e.preventDefault(); submit(); }}>
      <input
        type="text"
        onChange={e => (queryRef.current = e.target.value)}
      />
      <button type="submit">Search</button>
    </form>
  );
}

```

The `submit` function remains stable across renders, while the mutable query is stored in a ref. This avoids creating a new function for each keystroke while still accessing current input values.

## Best Practices for useCallback Optimization

- **Include all dependencies**: List every value referenced inside the callback in the dependency array to prevent stale closures.
- **Target memoized children**: Apply `useCallback` specifically when passing functions to components wrapped in `React.memo` or using `shouldComponentUpdate`.
- **Avoid overuse**: Do not wrap every callback; unnecessary memoization adds overhead without benefit when functions aren't props or effect dependencies.
- **Pair with useMemo**: Combine with `useMemo` when deriving complex objects that contain callbacks.
- **Use stable references**: Prefer refs or stable state selectors over mutable objects in dependency arrays.

## Summary

- React's `useCallback` Hook stores function references in [`ReactFiberHooks.js`](https://github.com/facebook/react/blob/main/ReactFiberHooks.js) and returns the cached version when dependencies match according to `areHookInputsEqual`.
- Parameters are defined in the callback signature but supplied at invocation time, allowing a single stable reference to handle multiple argument values.
- This optimization prevents child component re-renders and unnecessary effect executions in the facebook/react reconciler.
- The Hook is implemented in [`packages/react/src/ReactHooks.js`](https://github.com/facebook/react/blob/main/packages/react/src/ReactHooks.js) with core memoization logic residing in [`packages/react-reconciler/src/ReactFiberHooks.js`](https://github.com/facebook/react/blob/main/packages/react-reconciler/src/ReactFiberHooks.js).

## Frequently Asked Questions

### Can useCallback memoized functions accept dynamic parameters?

Yes. The memoized function returned by `useCallback` can accept parameters just like any standard function. Define the parameters in the function signature when creating the callback, then pass arguments when invoking it. React preserves the function reference while allowing different arguments at each call site, making react usecallback with a parameter effective for handling dynamic data without breaking referential equality.

### Does useCallback prevent re-creation when parameters change?

No. `useCallback` controls when the function reference changes based on the dependency array, not the arguments passed at invocation. The parameters supplied during the call do not affect memoization; only the dependencies listed in the second argument determine whether React returns a new function reference from `mountCallback` or `updateCallback`.

### When should I avoid using useCallback with parameters?

Avoid using this Hook for callbacks that are not passed as props to child components or included in dependency arrays of effects. The facebook/react source code shows that the reconciler's `mountCallback` and `updateCallback` functions add overhead to the render phase. If the callback is only used locally and never affects other components' render cycles, the optimization provides no benefit and adds unnecessary indirection.

### How does React compare dependencies in useCallback?

According to [`ReactFiberHooks.js`](https://github.com/facebook/react/blob/main/ReactFiberHooks.js), React uses `areHookInputsEqual` to perform shallow comparison of array elements. It checks each item in the new dependency array against the corresponding item in the previous array using strict equality (`===`). If any item differs, React creates a new callback reference; otherwise, it returns the cached function from the fiber's Hook node.