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>
);
};
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.