仅在点击时分配道具

时间:2018-12-04 18:23:58

标签: javascript reactjs redux react-redux

我遇到的问题是mapDispatchToProps将作为一个整体发送,我希望它仅在单击删除按钮后才发送。

这是我的课程,其获取fetchList很好,一切都按预期方式工作,但是当我添加了delete按钮后,它似乎一团糟,似乎在每次刷新页面时都调用了delete,知道为什么吗?

可能是我创建render()的地方Button,也许我没有单击就被触发了吗?仅通过创建列表即可,因为每次通过地图创建每个itemInList时都会触发该列表。

class List extends Component {
    componentWillMount() {
        this.props.fetchList();
    }

    componentWillReceiveProps(nextProps) {
        if (nextProps.newItem) {
            this.props.list.unshift(nextProps.newItem);
        }
    }

    onDelete = (id) => {
        this.props.deleteItem(id);
    }

    render() {
        const listItems = this.props.list.map(itemInList => (
            <div key={itemInList.id}> 
                <h3 className="title__font smaller">{itemInList.title} 
                    <Button 
                        btnType="Delete" 
                        onClick={this.onDelete(itemInList.id)}>
                        <i className="fas fa-trash-alt"></i>
                    </Button>
                </h3>
                <p className="body__font">{itemInList.body}</p>
            </div>
        ));
        return (
        <div>
            <h1 className="title__font">List</h1>
            { listItems }
        </div>
        );
    };
};

List.propTypes = {
    fetchList: PropTypes.func.isRequired,
    list: PropTypes.array.isRequired,
    newItem: PropTypes.object
};

const mapStateToProps = state => ({
    list: state.list.items,
    newItem: state.list.item
});

const mapDispatchToProps = dispatch => {
    return {
        fetchList: () => dispatch( actions.fetchList() ),
        deleteItem: (id) => dispatch( actions.deleteItem(id) )
    };
};

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

这是删除项目的操作:

export const deleteItem = (id) => dispatch => {
    console.log(id);
    dispatch({
        type: actionTypes.DELETE_ITEM,
        payload: filtered
    })
};

该日志在动作文件中被触发10次。

2 个答案:

答案 0 :(得分:1)

您正在立即调用onDelete,因此它将在渲染时分派。

尝试更换:

onDelete = (id) => {
  this.props.deleteItem(id);
}

使用

onDelete = (id) => () => this.props.deleteItem(id);

答案 1 :(得分:1)

您将要向onClick传递函数声明,并且需要以某种方式传递id。我们不想为性能问题在render方法中声明任何函数,但是我们需要某种方法在调用时将id传递给方法。数据属性是解决此问题的好方法。

这是一些相关文档。

首先,确保方法的this上下文已绑定到组件,如下所示:

constructor(props) {
  super(prop)

  this.onDelete = this.onDelete.bind(this)
}

以上是必需的,因为类方法实际上是在其原型上定义的,而不是在单个实例上定义的。旁注:如果您使用的构建系统具有类似于babel-plugin-proposal-class-properties的内容,则可以按以下方式声明您的方法:

onDelete = (e) => { this.props.deleteItem(e.target.dataset.id) }

您需要按以下方式更新onDelete方法:

onDelete = (e) => {
  this.props.deleteItem(e.target.dataset.id);
}

,您还需要像这样在渲染方法中更新Button标记:

<Button
    btnType="Delete"
    data-id={itemInList.id}
    onClick={this.onDelete}
>
    <i className="fas fa-trash-alt"></i>
</Button>

编辑:

这里是一个有效的Code Sandbox,以演示其工作原理。我必须对您的代码进行一些更改,例如排除未包含的<Button/>组件。我希望这可以帮助您到达需要的地方。