我遇到的问题是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次。
答案 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/>
组件。我希望这可以帮助您到达需要的地方。