javascript - Redux:动作触发了两次
问题描述
我有一个NavigationIcons
包含很少导航图标的组件,包括Add Item
图标。单击添加项目时,屏幕上会显示一个模式。模态有一个关闭按钮,所以当单击关闭按钮时,我希望模态从屏幕上消失。
问题是,当我单击以从导航按钮打开模式时,它会触发OPEN_ADD_ITEM_MODAL
并显示模式,当我尝试关闭它时,它会同时触发CLOSE_ADD_ITEM_MODAL
和OPEN_ADD_ITEM_MODAL
。我不明白它为什么会触发OPEN_ADD_ITEM_MODAL
,因为它仅onClick={() => props.openAddItemModal()}
用于 NavigationIcons 添加项目图标的事件中。
有人可以解释一下这里有什么问题吗?我在 NavigationIcons 中添加props.addItem
了依赖项,以便useEffect
在商店更改时重新呈现,但我仍然不知道。从console.log
NavigationIcons 始终显示true
。
导航图标组件
const NavigationIcons = (props) => {
useEffect(() => {
setSelectedHeaderNavigationIcon(props.headerNavigationIcon);
console.log(props.addItem);
}, [props.headerNavigationIcon, selectedHeaderNavigationIcon, props.addItem]);
return (
.....
<div className="add-item-icon" onClick={() => props.openAddItemModal()}>
{console.log(props.addItem)}
{props.addItem && <AddItemModal />}
<div className="main"></div>
</div>
.....
);
const mapStateToProps = (state) => ({
addItem: state.addItem.open,
});
const mapDispatchToProps = (dispatch) => ({
openAddItemModal: () => dispatch(openAddItemModal()),
});
export default connect(mapStateToProps, mapDispatchToProps)(NavigationIcons);
}
AddItemModal 组件
const AddItemModal = (props) => {
const handleModalClose = () => {
props.closeAddItemModal();
};
return ReactDOM.createPortal(
<div className="modal">
<ModalHeader handleModalClose={handleModalClose} />
...A lot of JSX
)
const mapDispatchToProps = (dispatch) => ({
closeAddItemModal: () => dispatch(closeAddItemModal()),
});
export default connect(null, mapDispatchToProps)(AddItemModal);
}
ModalHeader 组件
const ModalHeader = (props) => (
<div className="main">
Add item
<div className="close" onClick={() => props.handleModalClose()}>
close
</div>
<div>
)
Redux 操作
export const openAddItemModal = () => ({
type: AddItemActionTypes.OPEN_ADD_ITEM_MODAL,
});
export const closeAddItemModal = () => ({
type: AddItemActionTypes.CLOSE_ADD_ITEM_MODAL,
});
Redux reducer(我只有 1 个案例,用于切换,打开:!state.open,但因为我看到状态确实改变了关闭模式,所以决定显式打开/关闭)
const INITIAL_STATE = {
open: false,
};
const addItemReducer = (state = INITIAL_STATE, action) => {
switch (action.type) {
case AddItemActionTypes.OPEN_ADD_ITEM_MODAL:
return {
...state,
open: true,
};
case AddItemActionTypes.CLOSE_ADD_ITEM_MODAL:
return {
...state,
open: false,
};
default:
return state;
}
};
解决方案
由于您的 AddItemModal 嵌套在打开它的 div 中,因此事件会冒泡到父级并触发其 onClick。
添加event.stopPropagation
到 handleModalClose 函数:
const handleModalClose = evt => {
evt.stopPropagation();
props.closeAddModal()
}
或者只是将 AddItemModal 创建为同级,而不是所述 div 的子级。
推荐阅读
- apache-spark - 在 Spark 中连接所有列并转储为 json
- arrays - MongoDB查询数组+索引
- r - 饼图表示一个上下文的 18 小时和另一个上下文的 6 小时 - ggplot2
- makefile - 在makefile中使用编译器的shell别名或完整路径名?
- python - 如何在列表中找到重复序列
- angular - Angular - 'IContact[] 类型的参数 | 未定义的'不可分配给'IContact []'类型的参数
- javascript - Django - 静态图像不从 JavaScript 文件呈现
- python - 如何将嵌入矩阵(来自 CSV)保存为张量流嵌入检查点?
- sdk - Apify SDK Actor 监控
- python - 即使被调用的函数已经在我的班级中,我也会收到 NameError