redux-utilities / redux-promise

FSA-compliant promise middleware for Redux.
MIT License
2.67k stars 134 forks source link

Examples #19

Closed gsklee closed 4 years ago

gsklee commented 8 years ago

Please add some more comprehensive examples.

eriknyk commented 8 years ago

+1

aniss commented 8 years ago

+1

jingzhou123 commented 8 years ago

+1

jjzazuet commented 8 years ago

+1

drhayes commented 8 years ago

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.

cncolder commented 8 years ago

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: {},
    })
waynelkh commented 8 years ago

@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?

cncolder commented 8 years ago

@waynelkh redux-promise only dispatch one action after promise resolved. So I have no another better idea.

code-by commented 7 years ago

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 )

acpower7 commented 7 years ago

+1