How I Fixed: Uncaught ReferenceError: dispatch is not defined

It’s always a fun time when you hit an error, and you google it, and there’s no #1 result for a StackOverflow post, where someone far smarter than I can ever hope to be has already encountered, resolved, and shared their fix with some other unfortunate soul.

You mean I have to engage my brain and think? World, you can be cruel.

Anyway, tonight’s error (or one of them) was this :

Uncaught ReferenceError: dispatch is not defined

It had me stumped for a while. This is a React app – based on a starter project. So, more than likely, this was my goof.

Anyway, I had myself some forethought and had followed the convention of adding PropTypes to the class I am working on.

See if you can spot the mistake:

import React, { Component, PropTypes } from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { myAction } from '../actions/someOfMyActions';

class MyClass extends Component {

  constructor(){
    super();
  }

  componentDidMount() {
    const { myAction } = this.props;
    dispatch(myAction('a','b'));
  }

  render() {
    // blah
  }

}

function mapStateToProps(state) {
  return {
    appState: state
  };
}

function mapDispatchToProps(dispatch) {
  return {
    actions: bindActionCreators({
      myAction
    }, dispatch)
  };
}

MyClass.propTypes = {
  appState: PropTypes.object,
  loading : PropTypes.bool,
  items : PropTypes.array
};

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(MyClass);

Given that apparently, dispatch is not defined, I figured I would add it to the propTypes and see what kind of thing either was, or was not being passed in.

MyClass.propTypes = {
  appState: PropTypes.object,
  dispatch: PropTypes.function,
  loading : PropTypes.bool,
  items : PropTypes.array
};

That led to a new error. Which is good and bad.

Func, Not Function

It means what I did had some noticeable impact, but not the kind of impact that implies it’s resolved:

Warning: Failed prop type: MyClass: prop type `dispatch` is invalid; it must be a function, usually from React.PropTypes.
    in MyClass (created by Connect(MyClass))
    in Connect(MyClass)
    in Provider

Weird.

Looking back over the propTypes I suddenly remembered, it’s not function, it’s func. This caught me out last time.

The error could be nicer I guess.

MyClass.propTypes = {
  appState: PropTypes.object,
  dispatch: PropTypes.func,
  loading : PropTypes.bool,
  products : PropTypes.array
};

Updated, saved, and thanks to hot reloading, that error had gone before I’d tabbed back to my browser.

Cool.

But the problem wasn’t yet resolved. Actually, at this point I’d essentially made little progress in solving the problem.

I had confirmed dispatch was a function though:

Uncaught ReferenceError: dispatch is not defined;

Looking at the problem code again:

  componentDidMount() {
    const { myAction } = this.props;
    dispatch(myAction('a','b'));
  }

At this point I knew this was my boob for sure, and likely the error was staring me right in the face.

So, I did what any code goon would do, and I stuck in a console.log to figure out what the heck was on the props . In a second, you will see why this should have been obvious:

  componentDidMount() {
    const { myAction } = this.props;
    console.log('props', this.props);
    dispatch(myAction('a','b'));
  }

Which output a bunch of stuff which is quite hard to copy / paste in.

Anyway, it turned out on the props  was actions, which just so happened to contain the output from the function I had already declared:

function mapDispatchToProps(dispatch) {
  return {
    actions: bindActionCreators({
      myAction
    }, dispatch)
  };
}

doh!

RTFM Chris.

So I could update the call to:

  componentDidMount() {
    const { myAction } = this.props.actions;
    myAction('a','b');
  }

And what-do-you-know?! It worked!

Obvious, in hindsight.

By the way, I appreciate to any season React devs that this is likely a big “durrrr” moment.

Hopefully it saves someone a headache somewhere down the line.