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

Suggestion: Warn when bindActionCreators encounters non-function property #2279

Merged
merged 1 commit into from
Mar 8, 2017

Conversation

artgillespie
Copy link
Contributor

I've found myself debugging 'Dude, where's my prop?' situations when I've done something like

import { doSomething } from './actions' // for whatever reason, `doSomething` is `undefined`

...

const MyComponent = props => {
   ...
   const onClick = () => {
     props.doSomething() // error at runtime --> doSomething is undefined
   }
}

const mapDispatchToProps = {
  ...
  doSomething
  ...
}

It would speed up debugging in these situations if bindActionCreators logged a warning when it's passed an object with non-function properties.

@timdorr
Copy link
Member

timdorr commented Mar 4, 2017

Seems reasonable to me. Anyone else have any input?

@markerikson
Copy link
Contributor

markerikson commented Mar 4, 2017

Seems reasonable.

(Also, I should actually read prior comments more carefully so I don't sound like I'm just parroting someone else :) )

@timdorr
Copy link
Member

timdorr commented Mar 8, 2017

OK, let's merge it in.

@timdorr timdorr merged commit 1b154e0 into reduxjs:master Mar 8, 2017
@sebcode
Copy link

sebcode commented Jun 19, 2017

I think the automatic filtering was quite convenient for projects where you define both action creators and action types in the same file and then do import * as actions from 'actions' in your container and use that as second argument for connect().

This usage pattern is also used in the official universal example that now throws warnings.

container.js:

import * as actions from 'actions'

[...]

export default connect(mapStateToProps, actions)(Counter)

actions.js:

export const SET_COUNTER = 'SET_COUNTER'
[...]

export const set = (value) => ({
  type: SET_COUNTER,
  payload: value
})
[...]

Not sure if that approach is considered outdated, but at least I use it in my project a lot and it's still described in the official docs.

The not so pretty workaround I use now in my project:

export default connect(mapStateToProps, { ..._.pickBy(actions, a => _.isFunction(a)) })(Counter)

@kulakowka
Copy link

I updated the redux to 3.7.0 and got the error:

bindActionCreators expected a function actionCreator for key '__esModule', 
instead received type 'boolean'.

Tell me how to fix it? Have any ideas?

@elrumordelaluz
Copy link

elrumordelaluz commented Jun 19, 2017

I found the warning a source of some problems or misunderstanding.

I replied some questions related.

Since the application code continues working as expected (at least in my usecase), could be helpful if the the warning is a console.warn() instead of an console.error. Maybe with another util?

@anishmprasad
Copy link

Try this

import { action1,action2, … } from '../action'
// component
export default connect(mapStateToProps,{
  action1,
  action2,
  …
})(component);

@aghreed
Copy link

aghreed commented Jun 19, 2017

I have to agree with @sebcode.

Importing in actions with import * as action from 'actions' is definitely a common pattern, and one that saves a lot of headache when you've got larger actions files. Using the * import not only saves me from a giant import block, but also stops issues of variables being declared in upper scope when you use destructuring assignment.

import { action1, action2, ... } from 'actions'
...
class App extends Component {
...
componentWillMount() {
  const { action1 } = this.props; // <-- action1 is now already defined in upper scope
  action1();
}
...
export default connect(
  mapStateToProps,
  mapDispatchToProps,
)(App));

Now I get that you could export out of your actions files differently or add a little util function (like @sebcode is using) to pull out any non-function values pulled in with import * to solve this - but in my opinion these changes are more disruptive and time consuming than the original issue here of "dude where's my props".

@vhpoet
Copy link

vhpoet commented Jun 23, 2017

@artgillespie any possibility of reverting this? The error is super annoying.

@geminiyellow
Copy link

geminiyellow commented Jun 23, 2017

this merge is really a bad idea.

@timdorr
Copy link
Member

timdorr commented Jun 23, 2017

@markerikson @gaearon What do you think? This seems to be getting a lot of people in trouble with how Babel puts extra properties on modules (default and _esModule, by default). Outside of special casing those properties, which seems like the wrong solution, I think we should just remove this for now.

@markerikson
Copy link
Contributor

Well, on the one hand, it is just a warning. On the other hand, it does seem to clash with how Babel currently works, and our own samples show the usage pattern that leads to that warning.

Given that bindActionCreators appears to skip over non-functions already, I'm okay with dropping the warning.

(I'm also still seeing pros and cons for having filtering for only functions in stuff like compose.)

@betoharres
Copy link

I think that at least a warn instead of error message on the console would better suit this situation. When I saw the error msg I expected that my code was broke and things related to the error wasn't working, turns out it's just a warning, actually.

@digitalmaster
Copy link

Agree that downgrading to a warning will be better but this should really just be reverted :-/

@timdorr
Copy link
Member

timdorr commented Jun 26, 2017

Wait, our warning isn't a warning? Hmmm... 🤔

Anyways, I'll look at getting this change reverted shortly. I need to switch laptops, but I'll do that tonight.

@psychobolt
Copy link

Running tests with Jest will see it as a console.error:

console.error node_modules\react-native\Libraries\Core\ExceptionsManager.js:71
      bindActionCreators expected a function actionCreator for key 'Actions', instead received type 'object'.

@artgillespie
Copy link
Contributor Author

OP here... I'll get the revert PR together now. Sorry for all the trouble.

artgillespie pushed a commit to artgillespie/redux that referenced this pull request Jun 26, 2017
artgillespie pushed a commit to artgillespie/redux that referenced this pull request Jun 26, 2017
@artgillespie artgillespie mentioned this pull request Jun 26, 2017
timdorr pushed a commit that referenced this pull request Jun 26, 2017
@timdorr
Copy link
Member

timdorr commented Jun 26, 2017

Reverted and pushed out in 3.7.1. Thanks for the feedback everyone!

@elrumordelaluz
Copy link

Wait, our warning isn't a warning? Hmmm... 🤔

@timdorr I tried to say that here 👇

could be helpful if the the warning is a console.warn() instead of an console.error

@gaearon
Copy link
Contributor

gaearon commented Jun 26, 2017

Sorry I didn't chime in on this. That's exactly the reason we didn't do this in the first place 😛

@gaearon
Copy link
Contributor

gaearon commented Jun 26, 2017

Even filtering __esModule would not work well because people often export constants as named exports from the same file.

seantcoyote pushed a commit to seantcoyote/redux that referenced this pull request Jan 14, 2018
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.