event.stopPropagation似乎阻止useState更新和渲染

时间:2019-05-13 17:59:15

标签: reactjs state material-ui react-hooks stoppropagation

列表中有多行是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()进行测试。单击删除图标,然后观察没有任何反应。然后单击该行以展开面板,然后注意到它消失了。谢谢!

1 个答案:

答案 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);
};