DEV Community

Cover image for How to use React useReducer asynchronously
Gatesvert81
Gatesvert81

Posted on

How to use React useReducer asynchronously

Introduction

When building large projects with large states, managing them becomes a lot, in this case using a reducer function helps extracts logic for optimizing performance and making the code simple and readable. According to the official React page

useReducer
 is usually preferable to useState
 when you have complex state logic that involves multiple sub-values or when the next state depends on the previous one.

Because of the way useEffect is implemented, coming from redux, you can’t use it as a asynchronous function. But from my scouting and try and error, I found an easy way to implement it asynchronously.

Implementation

Let’s say we want to fetch some data from an Api and add it to our App.

const initialState = {
  posts: [],
};

const reducer = async (state, action) => {
  const { type, payload } = action;
  switch (type) {
    case "getPost":
      const results = await axois.get(
        "https://jsonplaceholder.typicode.com/posts"
      );
      return {
        ...state,
        posts: {
          ...state,
        },
      };
    default:
      return state;
  }
};

import React, { useEffect, useReducer } from "react";

function Posts() {
  const [state, dispatch] = useReducer(reducer, initialState, third);

  useEffect(() => {
    dispatch({ type: "getPost" });

    console.log(state);
  }, []);

  return <div>Posts</div>;
}

export default Posts;
Enter fullscreen mode Exit fullscreen mode

this returns a Error in your code after dispatching the ‘getPost’ type.
To safely asynchronously fetch your data and add it to your state, you must fetch the data first before dispatching the reducer. By doing this we get our fetch results then add it to our state.

const initialState = {
  posts: [],
};

const reducer = (state, action) => {
  const { type, payload } = action;
  switch (type) {
    case "getPost":
      return {
        ...state,
        posts: {
          posts: payload.posts,
        },
      };
    default:
      return state;
  }
};

import React, { useEffect, useReducer } from "react";

function Posts() {
  const [state, dispatch] = useReducer(reducer, initialState, third);

  const handleGetPosts = async () => {
    const results = await axois.get(
      "https://jsonplaceholder.typicode.com/posts"
    );
    dispatch({
      type: "getPost",
      payload: {
        posts: results,
      },
    });
  };

  useEffect(() => {
    console.log(state);
  }, [state]);

  return <div>Posts</div>;
}

export default Posts;
Enter fullscreen mode Exit fullscreen mode

With this simple code we can use useReducer hook asynchronously. there are other methods, but I think this is the simplest method.

Conclusion

Hope this clearly solves your problem with implementing useReducer asynchronously.
!Thank you for reading this blog.
I post a blog weekly. Please don't forget to buy me a coffee, Mathias Martey. Follow me on twitter @blaq_xcobar

Top comments (0)