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

Checking that the return value of every store function inside compose… #174

Closed
wants to merge 5 commits into from

Conversation

honzatrtik
Copy link

…Stores is not undefined


export default function composeStores(stores) {
const finalStores = pick(stores, (val) => typeof val === 'function');

Object.keys(finalStores).forEach(key => {
invariant(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be a hard error, or a warning in dev?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gaearon I guess the answer to that is: would undefined be a valid state? If so, then I think that we should warn, otherwise fail :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's a symptom of problem but I'm not sure it's worth failing in production. It's like wrong propTypes.

…Stores is not undefined,

production triggers warning
for undefined actions, reducers act like identity function
@taylorhakes
Copy link
Contributor

@honzatrtik @gaearon I feel this is only needed during development. I think it would be best if we don't have this check in production. Wrap the whole thing in

if (process.env.NODE_ENV === 'production') {
 // code here
}

Instead of just changing the error type. It will make production performant and not need to go through unnecessary code checks.

Object.keys(finalStores).forEach(key => {
if (finalStores[key](dummyStore, dummyAction) !== dummyStore) {
const message = `Your ${key} Store must return the state given to it for any unknown actions.`;
if (process.env.NODE_ENV === 'production') {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's do it the other way.
In development, we warn. In production, we skip this whole check (lines 10 to 20).

@taylorhakes
Copy link
Contributor

I gave this some thought. This change might cause some issues. If someone has runtime type checking in their reducers, this will cause an error.

Also, If they have some type of reducer that counts the number of actions that go through the reducer no matter the action. This change will make their code always show a warning.

If we don't think either of those are likely, then the benefits outweigh those downsides.

@gaearon
Copy link
Contributor

gaearon commented Jun 24, 2015

If someone has runtime type checking in their reducers, this will cause an error.

What kind of type checking are you referring to?

If they have some type of reducer that counts the number of actions that go through the reducer no matter the action.

Reducers must be pure in Redux. That's a hard constraint but it's not currently enforced. It's better if we log a warning than just behave weirdly.

@taylorhakes
Copy link
Contributor

What kind of type checking are you referring to?
There are libraries that convert Flow/Typescript type definitions to runtime checks.

I am not sure if default Flow would allow this to pass if your reducer function doesn't have type Object for state.

For instance in the counter example, the reducer always expects a number type state. This check is passing an object to all reducers.

@gaearon
Copy link
Contributor

gaearon commented Jun 24, 2015

Oh, I see now.. I haven't really thought about Flow in the context of this change.
Let's hear others' thoughts about this.

@gaearon
Copy link
Contributor

gaearon commented Jun 25, 2015

My suggestion: pass undefined as the state and make sure the returned result is not undefined.

@gaearon
Copy link
Contributor

gaearon commented Jun 29, 2015

Thanks for the food for thought.
I don't plan to merge this PR as is because it is superseded by #191.

Please let me know if you would like to implement #191 (throw if undefined is returned) instead.
Sorry for the churn!

@gaearon gaearon closed this Jun 29, 2015
@honzatrtik
Copy link
Author

Yup, i will try to implement #191 & apropriate tests tonight...

@gaearon
Copy link
Contributor

gaearon commented Jun 30, 2015

I think @taylorhakes is working on this already: #193

@honzatrtik
Copy link
Author

oh, i see! ok then.

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

Successfully merging this pull request may close these issues.

4 participants