Javascript 预期onClick侦听器是一个函数,而不是获取类型object-react-redux

Javascript 预期onClick侦听器是一个函数,而不是获取类型object-react-redux,javascript,reactjs,redux,react-redux,Javascript,Reactjs,Redux,React Redux,正如标题中所解释的,我得到了错误 预期onClick侦听器是一个函数,而不是获取类型对象 但我无法理解为什么这不起作用。 据我所知,onClick侦听器是一个函数 import { bindActionCreators } from 'redux'; ... function mapDispatchToProps(dispatch) { return { addCharacterById: bindActionCreators(addCharacterById, dispatch)

正如标题中所解释的,我得到了错误 预期onClick侦听器是一个函数,而不是获取类型对象

但我无法理解为什么这不起作用。
据我所知,onClick侦听器是一个函数

import { bindActionCreators } from 'redux';
...
function mapDispatchToProps(dispatch) {
  return {
    addCharacterById: bindActionCreators(addCharacterById, dispatch)
  };
}
下面是错误来源的CharacterList组件

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);
你们觉得怎么样?
这里有什么问题?

onClick={this.props.addCharacterById(character.id)}
调用时,这部分代码将立即执行
render()
,而您可能要做的是:

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


记住,
onClick
的第一个参数是click事件

问题是您正在立即调用函数,然后剩下的是返回值,它可能不是函数

相反,您可以将该函数调用包装在一个arrow函数中,以解决您的问题。一旦单击,它将调用内部函数:

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);
import React,{Component}来自'React';
从'react redux'导入{connect};
从“../actions”导入{addCharacterById};
从“redux”导入{bindActionCreators};
类CharacterList扩展了组件{
render(){
//console.log('name:',this.props.characters[2].name);
返回(
人物
    {this.props.characters.map((character)=>{ 返回(
  • {character.name} this.props.addCharacterById(character.id)} >+
  • ); })}
) } } 函数MapStateTops(状态){ 返回{ 角色:国家 } } 导出默认连接(MapStateTops,{addCharacterById})(CharacterList);
有不同的方法可以做到这一点,例如,您可以将参数绑定到函数,如:

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

    只是作为一个例子分享,以便您了解发生了什么以及为什么第一种方法更具可读性。您可能想通过阅读文章
    https://ryanfunduk.com/articles/never-bind-in-render/

    如果你想拥有良好的实践,你需要改变一些事情

    首先,添加
    mapDispatchToProps
    函数

    import { bindActionCreators } from 'redux';
    ...
    function mapDispatchToProps(dispatch) {
      return {
        addCharacterById: bindActionCreators(addCharacterById, dispatch)
      };
    }
    
    其次,事件处理程序可以是:

    onClick={() => this.props.addCharacterById(character.id)}
    
    第三,导出组件:

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

    不要直接调用
    onClick
    事件中的函数。它将递归调用该方法。因此,将
    onClick
    输入作为回调方法

    换行

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


    “据我所知,onClick侦听器是一个函数。”你确定吗<代码>控制台。日志是一个函数。
    console.log(“Hello”)
    是一个函数吗?在哪里可以看到console.log(“Hello”)?这是一个类比
    this.props.addCharacterById
    是一个函数。
    this.props.addCharacterById(character.id)
    是函数吗?函数调用不是函数。函数调用返回一个值。您没有将函数作为
    onClick
    prop传递。您正在传递函数返回的值。嗯,是的。读其他答案,说同样的话。我想我现在明白了。你能解释一下为什么用bindActionCreators来代替下面的方法吗:函数mapDispatchToProps(dispatch){bindActionCreators({addCharacterById},dispatch);}哪一个更好?@faraz我在我的答案中加入了bindActionCreators函数,因为您的示例中有它,但实际上它不是必需的。bindActionCreators的唯一使用案例是,当您希望将一些动作创建者向下传递给一个不知道Redux的组件,并且不希望将dispatch或Redux存储传递给它时。内联函数是否对性能有害?使用内联函数:
    onClick={()=>this.props.addCharacterById(character.id)}
    。func和obj是引用类型,因此每次重新渲染应用程序时,render()方法中的每个func都将使用内存中的不同点重新创建。如果这是真的,请告诉我你为什么用inline func展示这个例子?嗨@dragon,我在SO中的所有答案都保持简单、清晰和有用。性能和优化是一个不同的话题,不要认为在用户提问时理解了这个问题,所以让我们也尊重这一点。一旦OP了解了原因/方式,只需阅读数十亿篇关于此的文章中的一篇,包括扩展它的原始React文档。这里有一篇关于它的好文章()。
    onClick={() => this.props.addCharacterById(character.id)}