async-awaitreact-reduxredux-thunkredux-toolkitdispatch-async

How make make await as useDispatch


Can you please explain why await on dispatch has no effect?.Use dispatch is synchronous by default. But is there any way to make it to async?

I have one issue by using dispatch and createAsyncthunk.I think it halts the render of other components. I may be wrong please suggest a better way to handle this rendering issue. I think dispatch is still synchronous.

//API services

    const getPersonLists = async (query) => {
        return await axios.get(`${endPoint}/person?page=${query.page}&perPage=${query.perPage}`);
    };
    
    const fetchPeronWithAsyncThunk = createAsyncThunk('userSlice/userList', async (query) => await getPersonLists(query));

//Slice

    const userSlice = createSlice({
        name: 'userSlice',
        initialState: {
            users: [],
            loading: false,
        },
        extraReducers: {
            [fetchPeronWithAsyncThunk.pending]: (state) => {
                state.loading = true;
            },
            [fetchPeronWithAsyncThunk.rejected]: (state) => {
                state.loading = false;
            },
            [fetchPeronWithAsyncThunk.fulfilled]: (state, action) => {
                state.loading = false;
                state.users = action.payload;
            },
        },
    });

//Component

 

    const MyComponent = () => {
        const { users } = useUserList(); //selector
        const dispatch = useDispatch();
    
        const getList = async () => {
            //await has no effect
            await dispatch(fetchPeronWithAsyncThunk({ page: 1, perPage: 10 }));
        };
        return (
            <div>
                <button onClick={getList}>Fetch user</button>
                <div>{users.length && users.map((user, index) => <div key={index}>{user?.name}</div>)}</div>
            </div>
        );
    };

Solution

  • await at that point has exactly the effect you are waiting for. But since you are in a closure your state will not update within your getList function.

    You can get the result of the thunk in your code though:

    const result = await dispatch(fetchPeronWithAsyncThunk({ page: 1, perPage: 10 })).unwrap();
    

    Also, you should be using the builder notation for extraReducers. We will deprecate the object notation you are using soon.