Reputation: 171
I'm creating a Reddit client on Redux and I have 2 store dispatches firing in the app:
// App()
const dispatch = useDispatch();
useEffect(() => {
const stateMatch = window.location.href.match(/state=([^&]*)/);
const codeMatch = window.location.href.match(/code=([^&]*)/);
if ((stateMatch && codeMatch) || localStorage.getItem("access_token")) {
dispatch(fetchUser());
dispatch(fetchSubs());
}
});
...
However, I want fetchUser()
to run and finish before fetchSubs()
can begin, as the former currently seems to ruin API calls for the latter while it's running. How can I solve this?
Upvotes: 1
Views: 2690
Reputation: 1812
Since you are using createAsyncThunk
you can do something like this:
dispatch(fetchUser())
.unwrap()
.then((user) => {
// do anything you want with user, or don't, also dispatch actions
dispatch(fetchSubs());
})
.catch((e) => {
// error in case of rejection inside createAsyncThunk second argument
console.log(e);
});
Explanation
Let's say const thunk = fetchUser()
so basically dispatch(fetchUser())
is the same as dispatch(thunk)
.
Redux's dispatch
function returns whatever its argument (the action) returns.
So in this case, dispatch(thunk)
returns whatever thunk
returns.
thunk
, based on how createAsyncThunk
works, returns a promise that either resolves to fulfilled action, or the rejected action. (those actions that you receive in extra reducers).
This is how you can access those actions:
dispatch(thunk).then(fullfilledAction=>...).catch(rejectedAction=>...`
RTK library also provides a method called unwrap
. Instead of those action objects I explained above, it lets you use the returned value from the 2nd argument of createAsyncThunk
.
export const fetchUser = createAsyncThunk("user/fetchUser", async () => {
const user = await Reddit.getUser().then(val => {
return val;
});
return user; // unwrap lets you use this instead of action objects.
})
Upvotes: 5
Reputation: 2237
Try this with pure react and redux hooks
...
const state = useStore(yourStore) //use your method to read state
const dispatch = useDispatch();
const checkValue = () => {
const stateMatch = window.location.href.match(/state=([^&]*)/);
const codeMatch = window.location.href.match(/code=([^&]*)/);
if ((stateMatch && codeMatch) || localStorage.getItem("access_token")) {
return true;
}
return false;
}
useEffect(() => {
if(checkValue())
dispatch(fetchUser());
}
}, []);
useEffect(() => {
if(checkValue() && state.authState)
dispatch(fetchSubs());
}
}, [state.authState]);
...
Upvotes: 0