Closed gsklee closed 4 years ago
+1
+1
+1
+1
Sorry if this is wrong place for this, but I thought examples around specific cases would be good. Here are some things that confuse me:
Let's say I have a function that returns a Promise for fetching the user's profile, called fetchUser
. If I do this: dispatch.setUser(fetchUser());
then redux-promise
handles everything, including if the Promise rejects. Great!
Now I have dependent actions. Based on something in the user profile I need to get something else. Now what? I end up with code that looks like this:
function fetchUser() {
// return a Promise...
}
function unwrapAction() {
if (action.error) { throw action.payload; }
return action.payload;
}
setUser(fetchUser())
.then(unwrapAction)
.then(user => dispatch(fetchEmailsForUser(user))
.catch(e => dispatch(notifyUser(e.message)));
That interstitial unwrapAction
things seems clumsy and makes me feel like I'm missing the point somewhere. AFAICT it needs to be there because dispatch is handing back the action I'm passing in and errors are properties of the action. If I don't do that my promise chain swallows errors that don't bounce through the store. That doesn't seem great either.
I think this module is design for work with redux-actions together.
// actions/login-user.js
export const loginUser = createAction('LOGIN_USER', api.postLoginUser)
// utils/api.js
// this return promise, you can use another e.g. fetch()
export const postLoginUser = user => socket.postAsync('/auth/login', user)
// reducers/login.js
const login = handleActions({
LOGIN_USER: {
// handle resolve
next: (state, action) => ({
username: '',
password: '',
error: {},
}),
// handle reject
throw: (state, action) => ({
...state,
error: action.payload, // error in payload
}),
},
}, {
username: '',
password: '',
error: {},
})
@cncolder thanks for your example.
How can I dispatch trigger an action to change { isLoading: false }
to { isLoading: false }
state ?
My idea is dispatch a start loading action to change isLoading state to be true, and catch the same async action with difference reducer.
// component.js
{this.props.loadingStatus ? <Loading /> : ''}
<button onClick={() => {
this.props.dispatch(Actions.startLoading());
this.props.dispatch(Actions.fetchRowData(10));
}> fetch data</button>
// Actions.js
export const fetchRowData = createAction('FETCH_ROW_DATA', api.getRowUser);
export const startLoading = createAction('START_LOADING');
// status.js reducers
export default handleActions({
FETCH_ROW_DATA: (state, action) => false,
START_LOADING: (state, action) => true,
}, false);
// teammate.js reducers
export default handleActions({
FETCH_ROW_DATA: {
next(state, action) {
return ({
...state,
teams: state.teams.concat(action.payload),
});
},
throw(state, action) {
return {
...state,
message: action.payload.message,
};
},
},
...other actions
}, { team: [] });
// initialState
{ loadingStatus: false, team: [] }
Is there any better way to do that?
@waynelkh redux-promise only dispatch one action after promise resolved. So I have no another better idea.
Any simple example when "If it receives a promise, it will dispatch the resolved value of the promise. It will not dispatch anything if the promise rejects." please )
+1
Please add some more comprehensive examples.