Expected onClick listener to be a function, instead got type object - react redux

The problem is that you're invoking the function immediately and then what's left is the return value, which might not be a function!

What you can do instead is wrap that function call inside an arrow function to solve your problem. It'll call the inner function once you onClick:

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


class CharacterList extends Component{

    render(){
        //console.log('name : ',this.props.characters[2].name);
        return(
            <div>
            <h3>Characters</h3>
        <ul>
        {this.props.characters.map((character)=>{
            return(<li key={character.id}>{character.name}
                <div
                onClick={() => this.props.addCharacterById(character.id)}
                >+</div>
                </li>);
        })}
        </ul>
            </div>

            )
    }
}

function mapStateToProps(state){
    return {
        characters:state
    }
}




export default connect(mapStateToProps,{addCharacterById})(CharacterList);

There's diferent ways of doing this, you could for example bind the parameter to the function, like:

{this.props.characters.map((character)=>{
    return(<li key={character.id}>{character.name}
        <div
        onClick={this.props.addCharacterById.bind(null, character.id)}
        >+</div>
        </li>);
})}

Just shared as an example, so that you understand what's going on and why the first approach is more readable. You may want to look into why .bind in render is a bad practice by reading the article https://ryanfunduk.com/articles/never-bind-in-render/


onClick={this.props.addCharacterById(character.id)} this part of your code will execute immediately upon render() is call what you may want to do instead is:

onClick={(e)=> {this.props.addCharacterById(e, character.id)}}

Remember the first parameter pass to onClick is the click event.


There are some things that you need to change if you want to have good practices.

First, add mapDispatchToProps function.

import { bindActionCreators } from 'redux';
...
function mapDispatchToProps(dispatch) {
  return {
    addCharacterById: bindActionCreators(addCharacterById, dispatch)
  };
}

Second, the event handler could be:

onClick={() => this.props.addCharacterById(character.id)}

Third, export your component:

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