简体   繁体   中英

'dispatch' Uncaught TypeError React-Redux

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM