createAsyncThunk – Redux ToolKit (RTK)

ref – https://blog.logrocket.com/using-redux-toolkits-createasyncthunk/

Redux store possesses great state management features, but it doesn’t know how to deal with asynchronous logic.

Redux can’t handle asynchronous logic simply because it doesn’t know what you want to do with the data you fetched.

Middleware has since been used in Redux applications to perform asynchronous tasks.
Redux Thunk’s middleware being the most popular package.

With Redux Toolkit,
Redux Thunk is included by default.
This allows createAsyncThunk to perform delayed, asynchronous logic before sending the processed result to the reducers.

The Slice

We create the Redux slice via createSlice function.
A slice is a function that contains your store and reducer functions used to modify store data
Its name is posts, and we initialize it with some default data.

As you can see we create a getPosts that uses createAsyncThunk function. We initialize its action type string as ‘posts/getPosts’.
This is used in reducers in switch statements to catch the data to be stored.

Then we implement the async functionality.

We do our async feature in there and then return the data.

  • Synchronous Requests – Within createSlice, synchronous requests made to the store are handled in the reducers object
  • Async Requests – Within createSlice, extraReducers handles asynchronous requests, which is our main focus

Asynchronous requests created with createAsyncThunk accept three parameters:

  1. an action type string
  2. a callback function (referred to as a payloadCreator)
  3. and an options object

ref – https://redux-toolkit.js.org/api/createAsyncThunk#payloadcreator

It’s important to note that payloadCreator accepts only two parameters:

  • custom argument that may be used in your request
  • thunkAPI is an object containing all of the parameters that are normally passed to a Redux Thunk function — like dispatch and getState. Take a look at all the acceptable parameters.

    The payloadCreator function will be called with two arguments:

    arg: a single value, containing the first parameter that was passed to the thunk action creator when it was dispatched. This is useful for passing in values like item IDs that may be needed as part of the request. If you need to pass in multiple values, pass them together in an object when you dispatch the thunk, like

    thunkAPI: an object containing all of the parameters that are normally passed to a Redux thunk function, as well as additional other options:

    • dispatch: the Redux store dispatch method
    • getState: the Redux store getState method

    For example, in this payloadCreator, we have the main object goalData, which has all the data packaged into an object, so that it can contain various properties and their values.

    Then we have thunkAPI, which has getState, and dispatch. In our example, it uses the getState, and then uses the auth slice to access its user’s token value:

    Whenever the payloadCreator is dispatched from a component within our application, createAsyncThunk generates promise lifecycle action types using this string as a prefix:

    pending: posts/getPosts/pending
    fulfilled: posts/getPosts/fulfilled
    rejected: posts/getPosts/rejected

    The three lifecycle action types mentioned earlier can then be evaluated in extraReducers, where we make our desired changes to the store. In this case, let’s populate entities with some data and appropriately set the loading state in each action type:

    Dispatching it in your UI

    By using useSelector and useDispatch from react-redux, we can read state from a Redux store and dispatch any action from a component, respectively.

    Example

    Given a fetch function in a service file.
    We have a function that takes in data, and a token.
    This function will be used in a payloadCreator.

    frontend/src/features/goals/goalService.js

    Thus, we receive this data and token from thunkAPI:

    frontend/src/features/goals/goalSlice.js

    1) So we import an action function from our slice.
    2) We then dispatch that action.