Estoy creando un cliente de Reddit en Redux y tengo 2 envíos de tiendas que se activan en la aplicación:
// 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()); } }); ... Sin embargo, quiero que fetchUser() se ejecute y finalice antes de que pueda comenzar fetchSubs() , ya que el primero actualmente parece arruinar las llamadas API para el segundo mientras se está ejecutando. ¿Como puedo resolver esto?
Como está utilizando createAsyncThunk , puede hacer algo como esto:
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); });Explicación
Digamos const thunk = fetchUser() , por lo que básicamente dispatch(fetchUser()) es lo mismo que dispatch(thunk) .
La función de dispatch de Redux devuelve lo que devuelve su argumento (la acción).
Entonces, en este caso, dispatch(thunk) devuelve lo que devuelve thunk .
thunk , según cómo funciona createAsyncThunk , devuelve una promesa que se resuelve en una acción cumplida o en una acción rechazada. (aquellas acciones que recibes en reductores extra).
Así es como puede acceder a esas acciones:
dispatch(thunk).then(fullfilledAction=>...).catch(rejectedAction=>...` La biblioteca RTK también proporciona un método llamado unwrap . En lugar de los objetos de acción que expliqué anteriormente, te permite usar el valor devuelto del segundo argumento de 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. })Prueba esto con ganchos puros de reacción y redux.
... 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]); ...