0

A quick background, I was working on a React-Redux app using an older version of this boiler plate project.

However, it had some issues going forward so I ported my code to the latest version of the same boiler plate project (did it yesterday).

So the issue I had before got resolved. The UI is loading and everything looks great, but when Button.onTouchTap() gets fired, it's throwing an error like below:

Uncaught TypeError this.props.dispatch is not a function

This was working fine before without any problems, not sure what's breaking it. :(

In my component, I use decorators to connect to the store, not mapStateToProps method (which is commonly the root of this problem afaik).

@connect((store) => {
  return {
    param1 : store.myReducer.param1,
    param2 : store.myReducer.param2,
    param3 : store.myReducer.param3,
    param4 : store.myReducer.param4,
  }
})

The error is getting thrown at the line below:

this.props.dispatch(myAction(this.state.param1, this.state.param2))

I'm totally confused and have been caught on this for a long time. Any help is appreciated, thanks! <3

3
  • dispatch in props? Commented Aug 3, 2017 at 15:39
  • I don't use mapStateToProps or mapDispatchToProps, rather I'm using @connect ((store)=>{ return {param: store.myReducer.myParam}}) Commented Aug 3, 2017 at 15:41
  • So you are using mapStateToProps :-) You are using it with the connect decorator. Can you edit your question with this part of your code ? Commented Aug 3, 2017 at 15:43

1 Answer 1

1

It is in general considered a bad practice to directly give access to the dispatch function in component. You should instead use the second argument of @connect decorator to map the actions you want to dispatch to the props of your component as simple callbacks.

This pattern makes your component dumb. It doesn't know that the callback is coming from redux or from its parent or from whatever other sources you can use. It reduce adherence of your component and makes it easier to test and maintain.

I have never used connect as a decorator but I suppose that you can use it this way

import { connect } from 'react-redux'
import { myAction } from '/path/to/action/file'

@connect(
  state => ({ param: state.myReducer.myParam }),
  { myAction }
)

const MyComponent = props => {
  const { param, myAction } = props

  return (
    <div>
      <p>{ param }</p>
      <button onClick={ myAction }>Click Me</button>
    </div>
  )
}

export default MyComponent

Bad practice solution

If you really want your code to juste work as it is juste connect you component and give it the dispatch function in props.

import { connect } from 'react-redux'
import { myAction } from '/path/to/action/file'

@connect(
  state => ({ param: state.myReducer.myParam }),
  dispatch => ({ dispatch }),
)

const MyComponent = props => {
  const { param, dispatch } = props

  return (
    <div>
      <p>{ param }</p>
      <button onClick={ () => dispatch(myAction()) }>Click Me</button>
    </div>
  )
}

export default MyComponent

But again, this should not be done in real world application and should be refactored as showed in the beginning of this answer.

Sign up to request clarification or add additional context in comments.

4 Comments

I think I kinda understand what you're saying, can u please edit your answer to give an example of how I can achieve that? I also understand that @connect is a bad idea. But I was building this while learning react-redux, kinda tough to go back and change it at all places. Thank you! ;-)
I've updated the question with decorator, just for reference @Emrys Myrooin. I'm trying your changes, although the error is gone, it's acting a lil weird. If the request throws 401, it works fine, but if it's to throw a 200, it just doesn't respond. I'm looking more into it.
Hey @EmrysMyrooin, some new info. The query is getting fired and I'm receiving response, the only thing that's throwing an error is the method 'this.props.dispatch'. I don't know why it's happening. Also, the dispatched action.type is not getting caught in the reducer. :O
The thing is that you have to refactor your code to not use this.props.dispatch and use action by props like in my example ! But if you don't want to refactor, I have made an update that will correct the error.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.