I’m familiar with react hooks, and i find it really easy to work with useEffect, thunk is very difficult to deal with, can i just use useEffect & axios and just dispatch the result to the store without using createAsyncThunk? is there any major performance benefit to use it over useEffect?
createAsyncThunk:
import { createAsyncThunk, createSlice } from '@reduxjs/toolkit' import { userAPI } from './userAPI' // First, create the thunk const fetchUserById = createAsyncThunk( 'users/fetchByIdStatus', async (userId, thunkAPI) => { const response = await userAPI.fetchById(userId) return response.data } ) // Then, handle actions in your reducers: const usersSlice = createSlice({ name: 'users', initialState: { entities: [], loading: 'idle' }, reducers: { // standard reducer logic, with auto-generated action types per reducer }, extraReducers: { // Add reducers for additional action types here, and handle loading state as needed [fetchUserById.fulfilled]: (state, action) => { // Add user to the state array state.entities.push(action.payload) } } }) // Later, dispatch the thunk as needed in the app dispatch(fetchUserById(123))
useEffect:
import React, { useEffect } from 'react'; import { useDispatch } from 'react-redux' import { userAPI } from './userAPI' import axios from 'axios'; function App() { const dispatch = useDispatch() useEffect(() => { axios .get(userAPI) .then(response => dispatch({type:'fetchUsers',payload:response.data})); }, []);
Advertisement
Answer
The two setups are essentially similar. You can do the same thing with both approaches.
With the codes exactly as you have them written here, there is a major advantage to the createAsyncThunk
approach because it will catch
any errors that occur in the API call. It will respond to those errors by dispatching a fetchUserById.rejected
action instead of a fetchUserById.fulfilled
action. Your reducer doesn’t responded to the rejected
case which is fine. The error is still caught. With your useEffect
you run the risk of “uncaught error in Promise” errors.
Now of course you can catch
the errors on your own. You can also dispatch
a pending
action at the start of the effect. But once you start doing that, the createAsyncThunk
might feel a lot easier by comparison since it automatically dispatches pending
, fulfilled
, and rejected
actions.
useEffect(() => { dispatch({ type: "fetchUsers/pending" }); axios .get(userAPI) .then((response) => dispatch({ type: "fetchUsers", payload: response.data }) ) .catch((error) => dispatch({ type: "fetchUsers/rejected", payload: error.message }) ); }, []);