DEV Community

Cover image for Understanding useReducer and useRef in React
Jayashree
Jayashree

Posted on

Understanding useReducer and useRef in React

React gives developers many hooks to manage state and behavior inside components. Two hooks that often confuse beginners are useReducer and useRef. They solve different problems, and understanding when to use them makes React development much easier.

What is useReducer?

useReducer is a hook used for complex state management.

Normally we use useState:

const [count, setCount] = useState(0);
Enter fullscreen mode Exit fullscreen mode

But when state logic becomes larger — multiple actions, multiple state values, many updates — useReducer becomes useful.

Think of it like this:

Current State + Action → New State

Basic Syntax

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

state - current data
dispatch() - sends actions
reducer - function deciding how state changes

Example

import { useReducer } from "react";

function reducer(state, action) {
  switch(action.type) {
    case "increment":
      return { count: state.count + 1 };

    case "decrement":
      return { count: state.count - 1 };

    default:
      return state;
  }
}

function Counter() {

 const [state, dispatch] =
 useReducer(reducer,{count:0});

 return (
  <>
   <h1>{state.count}</h1>

   <button
    onClick={() =>
     dispatch({type:"increment"})}
   >
    +
   </button>

   <button
    onClick={() =>
     dispatch({type:"decrement"})}
   >
    -
   </button>

  </>
 );
}

Enter fullscreen mode Exit fullscreen mode

Why use useReducer?

Use it when:

  • State logic becomes complex
  • Multiple related states exist
  • Many updates depend on previous state
  • Large forms or complex UI logic

Simple idea:

useReducer = State management with actions

What is useRef?

useRef creates a value that stays the same between renders without causing re-rendering.

It is commonly used for:

  • Accessing DOM elements
  • Storing values without re-render
  • Keeping previous values

Syntax

const ref = useRef(initialValue);
Enter fullscreen mode Exit fullscreen mode

Example 1: Access DOM Element

import { useRef } from "react";

function App() {

 const inputRef = useRef();

 function focusInput(){
  inputRef.current.focus();
 }

 return(
  <>
   <input ref={inputRef}/>

   <button onClick={focusInput}>
    Focus
   </button>
  </>
 );
}

Enter fullscreen mode Exit fullscreen mode

When button clicked -> input automatically focused.

Example 2: Store Value Without Re-render

function App(){

 const count = useRef(0);

 function increase(){

  count.current++;

  console.log(count.current);

 }

 return(
  <button onClick={increase}>
   Click
  </button>
 );

}

Enter fullscreen mode Exit fullscreen mode

This updates value, but component does not re-render.

Why useRef?

Use when:

  • Need DOM access
  • Store mutable values
  • Prevent unnecessary re-renders
  • Save previous values

Simple idea:

useRef = Store something without re-rendering

Hook Purpose
useState Simple state management
useReducer Complex state logic and multiple state updates
useRef Store values without causing re-render

Final Thoughts

useState is enough for many situations.

When state logic grows bigger -> use useReducer.

When you need to remember something without re-rendering or access DOM elements -> use useRef.

Learning these hooks helps you build larger React applications more cleanly and efficiently.

Top comments (0)