【问题标题】:event.stopPropagation seems to prevent useState update and renderevent.stopPropagation 似乎阻止了 useState 更新和渲染
【发布时间】:2019-09-30 17:24:09
【问题描述】:

列表中有多行是 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() 之后运行的点击事件函数打开。

所以接下来我尝试使用 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

我将 event.stopPropagation() 留在 onDelete() 函数中进行测试。单击删除图标,然后什么也没有发生。然后单击该行以展开面板并注意它消失了。谢谢!

【问题讨论】:

  • 请创建一个CodeSandbox 重现您的问题。 event.stopPropagation() 不应该对状态更改是否导致重新渲染产生任何影响。
  • 添加了上面代码沙箱的链接。谢谢!

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


【解决方案1】:

React 避免了重新渲染,因为您使用完全相同的对象调用状态设置器。您应该创建一个新对象而不是改变现有对象,以确保 setter 触发重新渲染。

改变这个:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-15
    • 2020-03-03
    • 2018-07-19
    相关资源
    最近更新 更多