Search code examples
reactjsreduxredux-thunkredux-toolkit

Making an API call after dispatch


I am using React with Redux-toolkit. Let's say I need to fetch some data (let it be an array of numbers), then display those numbers on the page as a list, and then immidiately loop that array and make an API request using each number as an argument. This should happen by clicking on a button. So, button component looks like this:

export const Button: React.FunctionComponent = () => {
  const dispatch = useDispatch()
  const onClickButton = () => {
    dispatch(fetchNumbers())
  }

  return (
    <Button onClick={onClickButton}>
      <Icon />
      <Text>Run</Text>
    </Button>
  )
}

this is extra reducers:

export const fetchNumbers = createAsyncThunk(
  'data/numbers',
  async () => {
      return await someAPICall()
  }
)

export const fetchItem = createAsyncThunk(
  'data/item',
  async (number: number) => {
    return await someAnotherAPICall(number)
  }
)

Ideally, I want my logic to be like:

const onClickButton = () => {
    dispatch(fetchNumbers())
    .then(numbers => {
       numbers.forEach(num => fetchItem(num))
    })
  }

But unfortunatelly dispatch doesn't return a promise so I can't then after it. I know this is some elementary action but I found myself having no idea how to perform it using Redux-toolkit.


Solution

  • Actually, that dispatch(fetchNumbers()) does return a promise - buy your types don't reflect that.

    You need to correctly type your dispatch type as shown here in the documentation

    import { configureStore } from '@reduxjs/toolkit'
    import { useDispatch } from 'react-redux'
    import rootReducer from './rootReducer'
    
    const store = configureStore({
      reducer: rootReducer
    })
    
    export type AppDispatch = typeof store.dispatch
    export const useAppDispatch = () => useDispatch<AppDispatch>() // Export a hook that can be reused to resolve types