列表中有多行是Material-UI扩展面板。这些行是从rowData数组映射的。每行都可以扩展。每行还具有一个删除图标,按下该图标时应删除该行。
第一个问题是,当我单击DeleteIcon时,该行被删除,但是单击传播并打开以下面板。
<DeleteIcon
id={key}
onClick={event => {
onDelete(event, key); //key is specific row id
}}
className={classes.icons}
/>
const onDelete = (event, key) => {
let newCategories = categories;
delete newCategories[key];
setCategories(newCategories);
};
首先,我尝试将面板设置为false以将其关闭:
const [expanded, setExpanded] = useState(false);
...
const onDelete = (event, key) => {
setExpanded(false)
...
但这不起作用,因为我认为我的点击正在传播,并且删除的行下面的面板正在onDelete()之后运行的click事件函数中打开。
所以接下来我尝试使用event.stopPropagation:
const onDelete = (event, key) => {
event.stopPropagation();
let newCategories = categories;
delete newCategories[key];
setCategories(newCategories);
};
但是现在该行不会在视图中删除(在控制台中会删除)。我认为event.stopPropagation会阻止我的状态(setCategories)像useState挂钩中的更改那样强制重新渲染。但是,如果单击删除图标,则在单击该行以展开面板后,状态将更新,该行将被删除。所以我取出了event.stopPropagation,现在有了这个:
const onDelete = (event, key) => {
let newCategories = categories;
delete newCategories[key];
setCategories(newCategories);
setTimeout(() => {
setExpanded(false);
}, 100);
};
这行得通,并且在删除行之前非常简单地打开了以下面板,几乎没有效果,但是我想更好地了解使用event.stopPropagation以及使用useState挂钩更新状态。
编辑:
链接到codeandbox:https://codesandbox.io/embed/61j19k1q13
我在onDelete()函数中保留了event.stopPropagation()进行测试。单击删除图标,然后观察没有任何反应。然后单击该行以展开面板,然后注意到它消失了。谢谢!
答案 0 :(得分:2)
React避免了重新渲染,因为您使用完全相同的对象调用了状态设置器。您应该创建一个新对象,而不是对现有对象进行突变,以确保设置器会触发重新渲染。
更改此:
const onDelete = (event, key) => {
let newCategories = categories; // this line is the problem
delete newCategories[key];
setCategories(newCategories);
};
改为:
const onDelete = (event, key) => {
// create a new object rather than mutating existing object
let newCategories = { ...categories };
delete newCategories[key];
setCategories(newCategories);
};