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
feat(EpicMiddleware): warn about improper use of dispatch function #336
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yay! This is awesome. Thank you for spearheading this.
src/createEpicMiddleware.js
Outdated
const vault = (process.env.NODE_ENV === 'production') ? store : { | ||
getState: store.getState, | ||
dispatch: (action) => { | ||
store.dispatch(action); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to capture the return value of store.dispatch()
and return it from our wrapper, in case they have another middleware that returns something meaningful like redux-thunk, etc.
Something like
const result = store.dispatch(action);
console.warn(...);
return result;
src/createEpicMiddleware.js
Outdated
getState: store.getState, | ||
dispatch: (action) => { | ||
store.dispatch(action); | ||
console.warn(`Your Epic "${epic.name || '<anonymous>'}" called store.dispatch directly. This is an anti-pattern.`); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
epic.name
refers to the root epic in this scope I think? export function createEpicMiddleware(epic, ...
If so, it'll probably be confusing. You probably had this code originally inside the ::map(epic => {
scope, in which case epic
refers to the actual epic that did use store.dispatch
, but you'd have to create a "vault" for each epic, which I think is an ok tradeoff. 😄
While you're in here, you might change the root epic variable from epic
to rootEpic
to make it less confusing and prevent our ::map(epic => {
from shadowing it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm I moved the vault into the ::map but it seems the epic there is the root epic, and the name undefined. Maybe I can use the action.type in the warning message instead?
(I chose "vault" as a name for a store with more restrictions)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ohhh right, I forgot that inside the middleware we don't have access to the individual epics because they were composed with combineEpics
. I think I'll adjust it to just be generic and not mention which specific epic is to blame. I'm also going to change the message a bit to clarify that we're actually deprecating this (store.dispatch inside epics) and it will be removed in v1.0.0.
done(); | ||
}; | ||
const store = createStore(reducer, applyMiddleware(epicMiddleware, mockMiddleware)); | ||
store.dispatch({ type: 'FIRST_ACTION_TO_TRIGGER_MIDDLEWARE' }); | ||
}); | ||
|
||
it('should warn about improper use of dispatch function', () => { | ||
sinon.spy(console, 'warn'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing a matching restore of the original at the end of the test, console.warn.restore()
test/createEpicMiddleware-spec.js
Outdated
|
||
store.dispatch({ type: 'PING' }); | ||
|
||
expect(console.warn.called).to.equal(true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you change to expect(console.warn.callCount).to.equal(1);
or something similar--just want to make sure console.warn is only called once.
🎉 woot! thank you @evertbouw!! Very much appreciated. |
closes #314