I am making multiple dispatch call in the homepage
Its was something like this.
useEffect(() => {
async function getStorageData() {
setLoading(true);
try {
await dispatch(fetchProductA());
await dispatch(fetchProductB());
await dispatch(fetchProductC());
await dispatch(fetchProductD());
await dispatch(fetchProductE());
} catch (err) {
console.log(err);
} finally {
setLoading(false);
}
}
getStorageData();
}, []);
The problem is that when calling the these api. I got an error when productC. So I made a dispatch call.
I try throwing an error but that not work because when I throw an error in productC the remaining product D and E will not be called because throw end the dispatch calling
Here is my api call.
export const fetchProductC = () => dispatch => {
return axios
.get('productsapi/fetchProductC', {
headers: {
'Content-Type': 'application/json',
},
})
.then(res => {
dispatch({
type: FETCH_NEW_PRODUCTS,
payload: res.data[0]
});
})
.catch(err => {
dispatch({
type: EMPTY_NEW_PRODUCTS,
});
console.log('fetching new product error');
//throw err;
});
};
Here is the reducer
case FETCH_NEW_PRODUCTS:
return {
...state,
listC: action.payload,
};
case EMPTY_NEW_PRODUCTS:
return {
...state,
listC: [],
};
Your code after ProductC can't run because it is skipped via catch.
You can write your code like below.
await dispatch(fetchProductA()).catch(handleErr);
await dispatch(fetchProductB()).catch(handleErr);
await dispatch(fetchProductC()).catch(handleErr);
await dispatch(fetchProductD()).catch(handleErr);
await dispatch(fetchProductE()).catch(handleErr);
You should never await a dispatch in the component. Read tutorials and refactor your data flow: Redux Async Data Flow, Async Logic and Data Fetching
Redux recommends you to use thunk to do this:
// fetchTodoById is the "thunk action creator"
export function fetchTodoById(todoId) {
// fetchTodoByIdThunk is the "thunk function"
return async function fetchTodosThunk(dispatch, getState) {
// dispatch an action to set a loading state
dispatch(/*...*/)
const response = await client.get(`/fakeApi/todo/${todoId}`)
// use your response and set a success state here
dispatch(todosLoaded(response.todos))
}
}
// Your component
function TodoComponent({ todoId }) {
const dispatch = useDispatch()
const { data, state } = useSelector(/* your selector */)
const onFetchClicked = () => {
// Calls the thunk action creator, and passes the thunk function to dispatch
dispatch(fetchTodoById(todoId))
}
}