usereducer

Master useReducer in React: 5 Key Examples & Practices

Understanding useReducer in React

 

React provides several hooks to manage state in function components. Among these, useReducer stands out as a powerful alternative to useState, especially for managing complex state transitions. In this guide, we will break down how to master the useReducer hook, share best practices, and walk through 10 practical examples to help you build better React applications.

Let’s dive deep into usereducer, understand its use cases, and learn when it’s better than other hooks.

How useReducer Works in React

The useReducer hook is based on the concept of a reducer function, familiar to those who have worked with Redux. It is a pure function that takes in the current state and an action, and returns a new updated state.

Unlike useState, which simply updates a value, useReducer is best suited when:

  • State logic is complex.

  • The next state depends on the previous state.

  • There are multiple related state values.

Basic useReducer Syntax Explained

Here’s the basic syntax of usereducer in react:

  • reducer: A function that determines how the state should change.

  • initialState: The initial value of the state.

  • state: The current state.

  • dispatch: A function to trigger state changes.

Example of a simple reducer:

  • state: The current state object (example: { count: 5 }).

  • action: An object that usually has at least a type property (example: { type: 'increment' }).

  • switch (action.type): Checks what kind of action you want to perform.

  • return: Always returns a new state object (important for keeping things immutable — not directly changing the old state).

Why Choose useReducer Over useState?

  • Better state organization: Manage complex logic cleanly.

  • Predictable updates: Actions define explicit state transitions.

  • Easier debugging: Centralized reducer functions.

  • Scalable code: Especially useful when the app grows.

10 Practical Examples of useReducer in React

 

Let’s now see 10 detailed examples of usereducer hook usage.

1. Basic Counter Example

  • useReducer import:
    → Brings in useReducer from React to manage complex state.

  • initialState:
    → Sets the starting state { count: 0 }.

  • reducer function:
    → Takes current state and action, and returns the new updated state.

  • Counter component:
    → Uses useReducer to get state and dispatch function.

  • dispatch:
    → Sends actions (increment or decrement) to the reducer.

  • UI (JSX):
    → Shows the current count and provides buttons to update it.

2. Managing Form State

  • initialState:
    → Starts with empty name and email fields.

  • reducer function:
    → Updates the specific field (name or email) without changing the rest of the state.

  • Form component:
    → Uses useReducer to manage form data.

  • handleChange function:
    → Dispatches the input’s name and value to update the correct field.

  • Inputs (UI):
    onChange calls handleChange, and inputs show the latest state values.

  • Output:
    → Displays the full state as a JSON string below the inputs.

3. Toggle Theme (Light/Dark Mode)

  • initialState:
    → Starts with the theme set to 'light'.

  • reducer function:
    → Switches the theme between 'light' and 'dark' when the toggle action is dispatched.

  • ThemeToggle component:
    → Uses useReducer to manage theme state and update it based on button clicks.

  • dispatch with toggle action:
    → When the button is clicked, the dispatch sends the action { type: 'toggle' } to the reducer.

  • state.theme in className:
    → Applies the current theme ('light' or 'dark') to the div‘s class name to dynamically change the theme style.

4. Managing Multiple Inputs

  • initialState:
    → Initializes username and password as empty strings.

  • reducer function:
    → Updates the corresponding field (username or password) in the state based on the name and value of the input field.

  • LoginForm component:
    → Uses useReducer to manage form state and updates the username and password based on user input.

  • dispatch with e.target:
    → When a user types into either the username or password input, the dispatch function is called, passing e.target (which contains name and value properties) to the reducer.

  • Inputs (UI):
    → The value of each input is tied to the corresponding state field (state.username or state.password), ensuring the inputs are controlled components.

5. Cart Management in E-commerce

  • initialState:
    → Starts with an empty array [] representing the cart.

  • reducer function:
    → Handles two actions:

    • add: Adds a product to the cart.

    • remove: Removes a product from the cart by filtering out the item with the given id.

  • Cart component:
    → Uses useReducer to manage the cart state, allowing items to be added and removed.

  • dispatch with add action:
    → When the “Add Product” button is clicked, an item is added to the cart with the id and name properties.

  • dispatch with remove action:
    → Each item in the cart has a “Remove” button that removes the item by dispatching the remove action with the item’s id.

  • Rendering the Cart:
    → The cart is rendered as a list of products. Each product has its name displayed along with a “Remove” button.

6. Step Wizard Form

  • initialState:
    → Initializes with step: 1, indicating the starting step in the wizard.

  • reducer function:
    → Handles two actions:

    • next: Increases the current step by 1.

    • previous: Decreases the current step by 1.

  • Wizard component:
    → Uses useReducer to manage the current step, and renders the current step and buttons to navigate between them.

  • dispatch with next action:
    → When the “Next” button is clicked, the step is incremented by 1.

  • dispatch with previous action:
    → When the “Back” button is clicked, the step is decremented by 1.

  • Displaying the current step:
    → The current step is displayed in the <p> element.

7. Show/Hide Password

  • initialState:
    → Initializes with showPassword: false, meaning the password is initially hidden.

  • reducer function:
    → Handles the action to toggle the visibility of the password:

    • toggle: Flips the showPassword state between true (show) and false (hide).

  • PasswordToggle component:
    → Uses useReducer to control the visibility of the password input field.

  • dispatch with toggle action:
    → Clicking the “Show/Hide” button dispatches the toggle action to change the showPassword state.

  • Password input type change:
    → The input field type switches between text (show password) and password (hide password) based on state.showPassword.

8. Notification Handler

  • initialState:
    → Initializes with message: '' and type: '' to store the message and its associated type.

  • reducer function:
    → Updates the state with the new message and type values based on the dispatched action.

  • Notifications component:
    → Uses useReducer to handle the state and display notifications with different types.

  • dispatch with success action:
    → Clicking the “Success” button triggers the dispatch to set the message to 'Success!' and type to 'success'.

  • dispatch with error action:
    → Clicking the “Error” button triggers the dispatch to set the message to 'Error occurred' and type to 'error'.

  • Notification display:
    → The message is displayed conditionally, and the notification type is applied dynamically to set the appropriate style (e.g., alert-success or alert-error).

9. Loading State Management

  • initialState:
    → Initializes with loading: false, meaning the process is not currently loading.

  • reducer function:
    → Handles two actions:

    • start: Sets loading to true, indicating the loading process has started.

    • end: Sets loading to false, indicating the loading process has finished.

  • Loader component:
    → Uses useReducer to track whether the system is loading or done and displays the appropriate message.

  • dispatch with start action:
    → Clicking the “Load” button triggers the dispatch with { type: 'start' } to set loading to true.

  • dispatch with end action:
    → Clicking the “Finish” button triggers the dispatch with { type: 'end' } to set loading to false.

  • Conditional rendering:
    → The component displays either “Loading…” or “Done!” based on the value of state.loading.

10. Complex Calculator

  • initialState:
    → Initializes with total: 0, starting the calculator with a total value of zero.

  • reducer function:
    → Handles three actions:

    • add: Increases the total by the value provided in the action.

    • subtract: Decreases the total by the value provided in the action.

    • reset: Resets the total back to 0.

  • Calculator component:
    → Uses useReducer to manage and update the total value.

  • dispatch with add action:
    → Clicking the “Add 5” button triggers the dispatch with { type: 'add', value: 5 }, adding 5 to the current total.

  • dispatch with subtract action:
    → Clicking the “Subtract 3” button triggers the dispatch with { type: 'subtract', value: 3 }, subtracting 3 from the current total.

  • dispatch with reset action:
    → Clicking the “Reset” button triggers the dispatch with { type: 'reset' }, setting the total back to 0.

  • Display the total:
    → The total is displayed dynamically, updating each time the state changes based on user input.

Best Practices for useReducer in React

  • Always keep reducer functions pure.

  • Use constants for action types to avoid typos.

  • Modularize reducer logic in large applications.

  • Handle default cases in reducers.

  • Avoid unnecessary re-renders by using React.memo if needed.

Frequently Asked Questions (FAQs)

 

What is useReducer in React?
  • useReducer is a React Hook that lets you manage complex state logic in a function component through a reducer function, providing an alternative to useState.
When should I use useReducer?
  • Use useReducer when state logic involves multiple sub-values, complex conditions, or depends on previous state transitions.
What’s the difference between useState and useReducer?
  • useState is simpler for single values.

  • useReducer is better for complex or related state changes that require multiple actions.

Can I replace Redux with useReducer?
  • In small applications, yes. useReducer manages local component state similarly to Redux but without the full global state management overhead.
How do I structure actions in useReducer?
  • Use type and optional payload inside action objects to clearly define what change should happen in your reducer.

Final Thoughts

 

Mastering the usereducer hook is a crucial skill for modern React developers. With a good grasp of useReducer in React, you can manage complex component states much more effectively, making your code scalable, maintainable, and professional.

Keep practicing these examples, and soon using usereducer will feel natural in your React development journey!

2 Comments

  1. This is a simple example of a reducer function in JavaScript. It demonstrates how to handle state changes in a predictable way. The reducer takes the current state and an action as arguments, then returns a new state based on the action type. It’s a fundamental concept in state management libraries like Redux. Why is using a reducer considered beneficial for managing application state?

Leave a Reply

Your email address will not be published. Required fields are marked *