期望 onClick 侦听器是一个函数,而不是得到类型对象 - react redux

IT技术 javascript reactjs redux react-redux
2021-05-12 04:18:30

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

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

这是错误来自的 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);

这是动作创建者

export const ADD_CHARACTER='ADD_CHARACTER';
export function addCharacterById(id){
    var action ={
        type:ADD_CHARACTER,
            id
        }
        return action;

}

那么,大家怎么看呢?这里有什么问题?

4个回答

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

您可以做的是将该函数调用包装在箭头函数中以解决您的问题。一旦你点击,它就会调用内部函数:

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);

有不同的方法可以做到这一点,例如,您可以将参数绑定到函数,例如:

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

仅作为示例共享,以便您了解发生了什么以及为什么第一种方法更具可读性。您可能想通过阅读文章来了解为什么 .bind in render 是一种不好的做法https://ryanfunduk.com/articles/never-bind-in-render/

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

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

记住传递给的第一个参数onClick是点击事件。

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

首先,添加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={() => this.props.addCharacterById(character.id)}