0

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>
        );
    };
Sukesh
  • 167
  • 3
  • 14

1 Answers1

4

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.

phry
  • 35,762
  • 5
  • 67
  • 81
  • Thanks, @phry for your answer. But I'm still figuring out the builder notation usage on my case. you are suggesting using builder notation instead of the current one right? – Sukesh Feb 08 '22 at 10:02
  • Yes. You find more examples of that in the [createAsyncThunk docs](https://redux-toolkit.js.org/api/createAsyncThunk#promise-lifecycle-actions) or the [Redux Tutorial](https://redux.js.org/tutorials/essentials/part-5-async-logic#reducers-and-loading-actions) – phry Feb 08 '22 at 10:14