DEV Community

Cover image for React useCallback and useReducer
G Gokul
G Gokul

Posted on

React useCallback and useReducer

useCallback:

  • useCallback is a React Hook that returns a memoized version of a callback function.
  • It is used to optimize performance by caching a function definition between re-renders of a component.

Syntax and How it Works:

useCallback accepts two arguments:

  1. The function you want to cache.
  2. A dependency array (the function will only be recreated if one of these dependencies changes).

import { useCallback } from 'react';

const memoizedFunction = useCallback(() => {
  doSomething(a, b);
}, [a, b]); // Only recreates if 'a' or 'b' changes
Enter fullscreen mode Exit fullscreen mode

When should you use it?

  • Passing functions to memoized child components
  • Function is a dependency in other Hooks

Difference between useCallback vs useMemo:

I

useReducer:

  • In React, useReducer is a built-in Hook used for managing complex state logic.
  • It is an alternative to useState.
  • While useState is great for simple state updates (like toggling a boolean or updating a single text string), useReducer is preferred when a component has multiple pieces of state that depend on each other or when the next state depends heavily on the previous state.

Basic Syntax:

const [state, dispatch] = useReducer(reducer, initialState);
Enter fullscreen mode Exit fullscreen mode

state: The current value of your state.
dispatch: A function you call to trigger a state update by sending an "action".
reducer: A pure JavaScript function that houses all your state transition logic. It takes the current state and the action, then returns the next state.
initialState: The starting value of your state.

When should you use it?
You should reach for useReducer if:

  • You have a state object with multiple sub-values (e.g., a form state with username, email, isValid, loading).
  • The next state depends on what the previous state was.
  • You want to decouple state update logic from the UI or components to make it more testable and readable

Difference between useState vs. useReducer:

on

example:

import React, { useReducer } from 'react';

// 1. Reducer function using if / else instead of switch
function counterReducer(state, action) {
  if (action.type === 'increment') {
    return { count: state.count + 1 };
  } 
  else if (action.type === 'decrement') {
    return { count: state.count - 1 };
  } 
  else if (action.type === 'reset') {
    return { count: 0 };
  } 
  // Default fallback if an unknown action type is provided
  else {
    throw new Error(`Unhandled action type: ${action.type}`);
  }
}

// 2. Component definition
function CounterApp() {
  const [state, dispatch] = useReducer(counterReducer, { count: 0 });

  return (
    <div style={{ padding: '20px', textAlign: 'center' }}>
      <h2>Count: {state.count}</h2>

      <button onClick={() => dispatch({ type: 'increment' })}>Increment</button>
      <button onClick={() => dispatch({ type: 'decrement' })} style={{ margin: '0 10px' }}>Decrement</button>
      <button onClick={() => dispatch({ type: 'reset' })}>Reset</button>
    </div>
  );
}

// 3. Export at the very end
export default CounterApp;
Enter fullscreen mode Exit fullscreen mode

Top comments (0)