1

I am trying to define an Async Thunk method that calls a basic async function and returns the data. I am going to subsequently use this data in multiple components.

I cannot achieve this without the Async Thunk method calling the API as many times as I have components using the method.

import React from 'react';

import { createAsyncThunk, createSlice } from '@reduxjs/toolkit';
import { useDispatch, useSelector } from 'react-redux'

// Async Thunk Method
const fetchUsers = createAsyncThunk(
  'users/fetchUsers',
  async (thunkAPI) => {
    console.log("Calling fetch")
    const response = await new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve("Done!")
        }, 1000)
    })
    return response
  }
)

const initialState = {
  entities: [],
  loading: 'idle',
}

const usersSlice = createSlice({
  name: 'users',
  initialState,

  extraReducers: (builder) => {
    builder.addCase(fetchUsers.fulfilled, (state, action) => {
      return {
        ...state,
        entities: action.payload,
        loading: 'fulfilled'
      }
    })
  },
})

export function useUsers() {
  const dispatch = useDispatch()
  const { entities, loading } = useSelector(state => state.users);
  console.log(loading)
    
  React.useEffect(() => {
    if (loading === 'idle') {
       dispatch(fetchUsers())
    }
  }, [loading]);

  return React.useMemo(() => ({
    entities
  }), [entities])
}

export default usersSlice.reducer;
function App() {
  /* This will cause the Async-Thunk to be called twice 
   * (goal is to be called once)
   */
  useUsers();
  useUsers();
}

I will be using this hook in multiple components, and for some reason, they are unable to see that the loading status is not idle after the first call, so many calls are made.

0 Answers0