Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

question: idiomatic way to reference dispatcher and/or state? #20

Open
tony-kerz opened this issue Nov 9, 2015 · 12 comments
Open

question: idiomatic way to reference dispatcher and/or state? #20

tony-kerz opened this issue Nov 9, 2015 · 12 comments

Comments

@tony-kerz
Copy link

hi andrew,

redux-thunk facilitates referencing dispatcher and state by automatically providing the dispatcher and getState methods.

how would you recommend gaining similar references using redux-promise?

regards,
tony

@tony-kerz tony-kerz changed the title question: idiomatic way to reference state? question: idiomatic way to reference dispatcher and/or state? Nov 9, 2015
@kevana
Copy link

kevana commented Nov 12, 2015

From this comment in July, using redux-thunk and redux-promise together looks like a pretty good pattern:

// Relies on both thunk and promise middleware
createAction('FETCH_SOMETHING', id => {
  // Thunk will be handled by thunk middleware
  return dispatch => {
    // Trigger optimistic update
    dispatch({ type: 'FETCH_SOMETHING_BEGIN', body: { id } });

    // Promise will be handled by promise middleware
    return api.fetch(id);
  }
});

@tony-kerz
Copy link
Author

thanks @kevana, i can get with that.

it seems like it might be an improvement to have those characteristics in a single piece of middleware, but for now it could qualify as "idiomatic" ;)

i'll leave this open as a placeholder for the idea of converging those middleware, but project owners can feel free to close if they feel this is a sufficient solution.

@tony-kerz
Copy link
Author

@kevana, i just tried the strategy outlined above, and the behavior i witnessed was the thunk not being executed.

the following doesn't take i think because createAction puts the 'thunk' in a payload field...?

export const setSkill = createAction(
  actions.SET_SKILL,
  (skill) => {
    return (dispatch, getState) => {
      dispatch(setSkillBegin(skill))
      return getArticlesPromise(skill)
    }
  }
)

i have however had some luck with something like:

export const setSkill = (skill) => {
  return (dispatch, getState) => {
    dispatch(setSkillBegin(skill))
    dispatch(createAction(actions.SET_SKILL, getArticlesPromise)(skill))
  }
}

@kevana
Copy link

kevana commented Nov 16, 2015

I don't have a working example, just stumbled across that comment and figured it might be helpful

@davibe
Copy link

davibe commented Mar 5, 2016

I do this

// Actions.js
import store from '../store';
import progress from './Progress/actions';

const myActionCreator = async (argument, dispatch = store.dispatch, getState = store.getState) => {
    dispatch(progress.start());
    const result = await doSomethingAsync();
    dispatch(progress.stop());
    return {
        type: 'MY_ACTION', payload: result
    };
}

This way i can call the function with just the argument from the components, but I can also specify them explicitly in my tests.

I don't use redux-actions. I just use plain redux connect() to bind and connect my action creators.

@davibe
Copy link

davibe commented Oct 20, 2016

Now that i am trying to render things server-side it looks like my way of importing the store directly is bad because on the serverside i must be able to change it at runtime from one request to another. What's the correct approach here ?

@insidewhy
Copy link

The best way of dealing with this is to use an alternate thunk middleware that looks for the function in payload. The thunk middleware is only 5 lines of js, trivial to replace. In mine I also dispatch the action with the return value of the thunk, this is great when you combine with promise middleware.

@davibe
Copy link

davibe commented Dec 6, 2016

Lately i ended up removing the promised middleware and using just redux-thunk alone. Looks like a thunk can return a promised value and if it does the dispatch() return value itself is a promise that you can await.

const actionCreator (params) => {
  return async (dispatch, getState) => { ... }
}

await dispatch(actionCreator({...}))

@insidewhy
Copy link

@davibe then you have an async reducer? I published redux-thunktions middleware that lets you handle this situation elegantly, there are some examples in the readme.

@davibe
Copy link

davibe commented Dec 23, 2016

I don't have an async reducer. Just the code i have written above works fine with redux-thunk. Inside that async method i can dispatch other async action but at some point the final actions actually modifying the state will be sync.

@insidewhy
Copy link

I see, but then you'll need boilerplate each time to handle promises rejections etc. It's better to use promise middleware to handle that so you have a consistent and terse way of handling asynchronous payloads.

@davibe
Copy link

davibe commented Dec 27, 2016

I am not sure what you mean. I have a "client action creator" that can dispatch success/error depending on the outcome of the api call. I use it in many other actions so I am no really repeating that code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants