How to Use Thunks with Redux Toolkit and TypeScript

Responses (2)

PlavnikA3 months ago

By writing "as" Type, in initialState, you just for thing typescript to admit, that is a right type, it's not guarding you...

Ther eis places, you have to us eit, but here, you need to use " : "


Like, const initialState: Type = {}


In that was, it will warn you if you right something wrong inside.. But when you use AS Type, it doesn't check what you write inside, it just will admit, that it's as this Type, even if you wrong.

Clap
1|2|

Last time we used Redux Toolkit to create a todo app. Since RTK is considered to be the standard way to write redux applications, we will use thunks with Redux Toolkit to write asynchronous logic as well.

Thunks#

Thunks are a way to manage side effects when working with Redux. For instance, when we want to fetch some data from a server we need to perform an HTTP request. That request is a side effect because it interacts with the “outer world”.

Redux itself doesn't know anything about side effects in an app. All the work is done in the redux-thunk middleware. It extends the store's abilities and lets you write async logic that interacts with the store.

Redux Toolkit's configureStore function automatically sets up the thunk middleware by default.

Async Logic#

Right now we have a todo app that works synchronously, so we can only use the runtime storage to store the user data. In real-life applications, we would need to store user's data in some kind of persistent storage, on a server for example.

Let's change our app a bit and, as an example, create a method to load todos from the server and show them.

Refactoring#

First of all, we're going to slightly refactor our previous code. We will extract our useTypedSelector from features/todos/TodoList.tsx to app/store.ts:

...This will help us to re-use this function in another component later.

Also, we will extract some todos types into features/todos/types.ts:

...Which will help us to cover the API requests with types.

Backend Mock#

As a backend, we will use JSON-placeholder. It allows us to fetch a list of todo-objects that we can render in our UI.

The endpoint we use returns a list of todo-objects

Fetch Todos Thunk#

RTK provides a function called createAsyncThunk for creating thunks. Let's start with creating one:

Let's write the real request logic using our placeholder backend:

Cool, now it's working. However, the result we return is not typed. TypeScript yet doesn't know about the structure of data we return.

For typing the result, we're going to need Todo type we extracted earlier:

Pro tip: we could also use a wrapper-function over fetch to make sure that every response is typed.

Okay, now our fetchTodos function doesn't take any argument. But let's think about a situation when we need to control the amount of fetched todos. We could use a function argument for that:

The only thing left to cover is errors. Imagine that the server responded with a status 400. In this case, we would need to tell our users that todos aren't loaded and show the error message.

Notice that TS cannot mix explicit and inferred generic parameters. If we want to use rejectWithValue we need to define return-type and payload creator argument type as well.

Adding Thunks to Slices#

Now, let's add our thunk to todosSlice. For that, we need to slightly change our TodosState:

After it's done, let's define a selector for getting the status value:

Finally, let's add reducers for handling our fetchTodos actions:

Using Thunks with Components#

The last thing to do is to use the fetchTodos thunk inside a component. Let's create a button, click on which will fetch a list of todos from a server.

Now we can use this component to load todos from the server.

Sources#

Clap
1|2