我遇到的问题是mapDispatchToProps是作为一个整体发送的,我希望它只有在单击删除按钮时才发送。
这是我的类,它获取fetchList很好,一切都按预期进行,但当我添加了删除按钮时,它似乎把一切都搞砸了,它似乎每次刷新页面都会调用delete,知道为什么吗?
它可能是我创建Button
的render()
吗?也许它在我不点击它的情况下被触发了?只需创建列表,因为每次通过映射创建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次。
您想要将函数声明传递到onClick
中,并且需要以某种方式传递id
。由于性能问题,我们不想在render方法中声明任何函数,但我们需要某种方法在调用时将id
传递到方法中。数据属性是这个问题的一个很好的解决方案。
以下是一些相关文档。
- React:处理事件
- HTMLElement.dataset
- babel插件建议类属性
首先,确保方法的this
上下文绑定到组件,如下所示:
constructor(props) {
super(prop)
this.onDelete = this.onDelete.bind(this)
}
以上是必需的,因为类方法实际上是在它们的原型上定义的,而不是在单个实例化上定义的。附带说明:如果你使用的构建系统具有类似babel插件提案类属性的东西,你可以如下声明你的方法:
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>
编辑:
下面是一个正在工作的代码沙盒来演示它是如何工作的。我不得不对您的代码进行一些更改,例如排除未包含的<Button/>
组件。我希望这能帮助你到达你需要的地方。
您将立即调用onDelete
,因此它将在渲染时进行调度。
尝试更换:
onDelete = (id) => {
this.props.deleteItem(id);
}
带有
onDelete = (id) => () => this.props.deleteItem(id);