1

I searched for answers to this one but didn't see any that matched my problem. I am trying to build a calculator app using React & Redux and whenever I click on one of the number buttons, I get an error that says "this.props.AppendCharacter is not a function"

Here is my relevant code:

number_button.js

import React, {Component} from 'react';
import {bindActionCreators} from 'redux';
import {connect} from 'react-redux';

import AnswerScreen from '../containers/answer_screen';
import AppendCharacter from '../actions/index';

class NumberButton extends Component {
    constructor(props) {
        super(props);

        this.state = { button: '' };
        this.clickButton = this.clickButton.bind(this);
    };

    clickButton() {
        this.props.AppendCharacter(this.props.number);
        console.log('clicked on ', this.props.number);
        this.setState({ button: this.props.number });
    }

    render(props) {
        return (
            <div className="number-button general-button" onClick={this.clickButton}>
            {this.props.number}
            </div>
        );
    };
};

function mapDispatchToProps(dispatch) {
    return bindActionCreators({ AppendCharacter }, dispatch);
};

export default connect(null, mapDispatchToProps)(NumberButton);

actions/index.js

export function AppendCharacter(character) {
    return {
        type: APPEND,
        payload: character
    };
};
PirateJohn
  • 58
  • 9

3 Answers3

0

You can accomplish what you need by changing your mapDispatchToProps to:

function mapDispatchToProps(dispatch) {
    return {
        AppendCharacter: (character) => dispatch(AppendCharacter(character));
    };
}

I'm not familiar with bindActionCreators, so someone else may need to weigh in if you need that functionality.


Side note: it doesn't look like you need the component state for button in your current set up. You may have plans for it, but it's unused in your example.

Luke Willis
  • 8,429
  • 4
  • 46
  • 79
  • Thank you. I tried it, but I got a different error that said "Uncaught TypeError: (0 , _index2.default) is not a function" (Oh, and I am probably going to remove the component state once I get this working -- I changed my design after adding that part. Thanks for the comment on that.) – PirateJohn Oct 06 '17 at 21:16
  • You're close. Sounds like this solved your problem. Now, you need to revisit how you're `import`ing and `export`ing. Sounds like you may have (or not have) a `default` export when you meant to (or didn't mean to). [this should help](https://stackoverflow.com/a/36796281/2479481) – Luke Willis Oct 06 '17 at 21:18
  • 1
    The original `mapDispatchToProps` was ok; `bindActionCreators` wraps action creators in calls to `dispatch()`. I woud suggest, though, that if you don't deeply understand how `dispatch()` works, you should not use `bindActionCreators` because it adds a potentially confusing layer over a concept that many already find confusing when they first start using redux. – stone Oct 06 '17 at 21:57
  • @PirateJohn this might also help with the `default` issue: https://github.com/gaearon/redux-thunk/issues/116#issuecomment-264629537 – Luke Willis Oct 06 '17 at 21:58
  • @skypecakes good to know. I'll have to read up on `bindActionCreators` now. :) – Luke Willis Oct 06 '17 at 21:59
0
const mapDispatchToProps = {
  AnswerScreen,
  AppendCharacter 
};

export default connect(null, mapDispatchToProps)(NumberButton);
SM79
  • 1,234
  • 2
  • 15
  • 33
  • Thank you. I tried your code but it still didn't work, unfortunately. – PirateJohn Oct 06 '17 at 21:14
  • This is a step in the right direction, but it won't work because it doesn't actually map dispatch to props. `mapDispatchToProps` needs to take a parameter `dispatch` and return functions that call `dispatch` for each action creator. See my answer for an example of one way to set this up. – Luke Willis Oct 06 '17 at 21:23
0

Well, I found the error. Someone on a different web site helped me. The bindActionCreators was working fine, but the problem was that when I import AppendCharacter from ../actions/index, I needed to wrap AppendCharacter in curly braces. I changed that and now the app works.

Whew!

Thank you everyone for your replies. I've learned a lot in these last few days!

PirateJohn
  • 58
  • 9