How to use React’s useActionState Hook

1 min read

How to use React’s useActionState Hook

The useActionState hook in React 19 enables developers to directly manage state updates triggered by predefined actions. It’s like a simplified version of useReducer, designed for scenarios where action-based state management is crucial.

Syntax of useActionState

The basic syntax is:

const [state, dispatch] = useActionState(initialState, actionHandlers);

initialState: The initial value of the state.

actionHandlers: An object mapping actions to their corresponding state transition functions.

Example: Counter Application

Here’s how you can use useActionState to create a counter:

Implementation

import React from "react";

function Counter() {
  const [state, dispatch] = useActionState(
    { count: 0 }, // Initial state
    {
      INCREMENT: (prevState) => ({ count: prevState.count + 1 }),
      DECREMENT: (prevState) => ({ count: prevState.count - 1 }),
      RESET: () => ({ count: 0 }),
    }
  );

  return (
    <div>
      <h1>Count: {state.count}</h1>
      <button onClick={() => dispatch("INCREMENT")}>Increment</button>
      <button onClick={() => dispatch("DECREMENT")}>Decrement</button>
      <button onClick={() => dispatch("RESET")}>Reset</button>
    </div>
  );
}

export default Counter;

How It Works

  1. State Initialization:
    • The useActionState hook initializes the state ({ count: 0 } in this example).
  2. Action Dispatching:
    • The dispatch function accepts an action name (e.g., "INCREMENT") and executes the corresponding handler defined in the actionHandlers object.
  3. State Transitions:
    • Each action handler updates the state based on the logic specified (e.g., count + 1 for "INCREMENT").

Benefits of useActionState

  1. Simplified State Management:
    • Handles action-driven state transitions without the complexity of reducers.
  2. Improved Code Readability:
    • Centralizes state transition logic within the actionHandlers object.
  3. Enhanced Reusability:
    • Can be used in multiple components with consistent patterns.

Example: Toggle Application

Let’s create a toggle switch using useActionState.

Implementation

import React from "react";

function ToggleSwitch() {
  const [state, dispatch] = useActionState(
    { isOn: false }, // Initial state
    {
      TOGGLE: (prevState) => ({ isOn: !prevState.isOn }),
      TURN_ON: () => ({ isOn: true }),
      TURN_OFF: () => ({ isOn: false }),
    }
  );

  return (
    <div>
      <h1>{state.isOn ? "Switch is ON" : "Switch is OFF"}</h1>
      <button onClick={() => dispatch("TOGGLE")}>Toggle</button>
      <button onClick={() => dispatch("TURN_ON")}>Turn ON</button>
      <button onClick={() => dispatch("TURN_OFF")}>Turn OFF</button>
    </div>
  );
}

export default ToggleSwitch;

Conclusion

The useActionState hook in React 19 streamlines action-based state management, making it simpler to write clean and maintainable code. By centralizing state transitions into an action handler map, it provides a more intuitive alternative to traditional reducers for specific use cases. This flexibility empowers developers to build robust and dynamic applications.

🤞 Never miss a story from us, get weekly updates to your inbox!