【问题标题】:Checkbox doesn't respond to onChange when checked is driven by stateCheckbox在选中时,未响应Onchange由状态驱动
【发布时间】:2020-09-14 17:50:16
【问题描述】:

我有一个 material-ui Table 并一直在其上实现多选功能。

我的多选应该表现如下:

  • 选择复选框仅在悬停时出现在行首(当未选择任何内容时)
  • 选择一行后,所有其他复选框将永久可见。
  • TableHead 中的复选框在切换时将选择/取消选择Table 中的所有行。

每一行都有自己独特的id

我通过useState 挂钩维护一个名为idsOfSelectedRowsSet,以跟踪当前选择的所有行。

每个TableRow 都有一个Checkbox,看起来像这样

<Checkbox
  className={
     idsOfSelectedRows.size === 0 &&
     styles.rowSelectionCheckboxStyle
  }
  onChange={() => handleRowSelectionCheckboxClick}
  checked={idsOfSelectedRows.has(row.id)}
 />

handleRowSelectionCheckboxClick 看起来像这样

  const handleRowSelectionCheckboxClick = event => {
    const idOfClickedRow = event.target.attributes.getNamedItem("id").value;
   //If the checkbox has just become checked then add it to the idOfSelectedRows Set, otherwise remove it.
    setIdsOfSelectedRows(
      event.target.checked
        ? new Set(idsOfSelectedRows.add(String(idOfClickedRow)))
        : () => {
            idsOfSelectedRows.delete(String(idOfClickedRow));
            return new Set(idsOfSelectedRows);
          }
    );
  };

我的问题是单击行上的复选框没有响应。我可以通过单击TableHead 中的全选 Checkbox 将它们全部选中,但单击单个行中的复选框不会改变它们的状态?

这是一个完整的 CodeSandbox,再现了确切的问题。 我需要做什么才能使行中的复选框可以切换?

【问题讨论】:

    标签: javascript html reactjs checkbox material-ui


    【解决方案1】:

    onChange 分配中删除() =&gt; 以便快速修复。

    为什么

    您正在声明一个匿名内联函数,但该函数不调用任何东西(缺少调用函数的语法())。 onChange 接受函数引用。当你给它一个内联函数时,这就是它会调用的函数。另一种选择是仅将handleRowSelectionCheckboxClick 的函数reference 传递给它,然后在更改时调用该函数而不是匿名函数中间人。

    所以你的两个选择是:

    onChange={handleRowSelectionCheckboxClick} // Just the reference
    

    onChange={(e) => handleRowSelectionCheckboxClick(e)} // New inline function that calls your function 
    

    在大多数情况下,第二种方式是不必要的。除非您需要传递自定义参数,否则首选第一个。以下是它可能有用的示例:

    onChange={(e) => handleRowSelectionCheckboxClick(e, id)}
    

    在您的沙盒中,您映射元素,每个元素都会获得一个更改处理程序。要在处理程序中分别处理它们,您可以像上面一样向函数传递一个额外的变量。

    例如,我通过更改处理程序和分配来让您的沙箱工作:

    const handleRowSelectionCheckboxClick = (event, idOfClickedRow) => {
    
    ...
    
    onChange={(e) => handleRowSelectionCheckboxClick(e, row.id)}
    

    【讨论】:

    • 不幸的是,这在我的 CodeSandbox 示例中仍然不起作用。
    • 您的沙盒看起来也有其他问题。与此特定问题无关。我用一个额外的相关示例更新了我的答案。
    【解决方案2】:

    这一行:event.target.attributes.getNamedItem("id").value; 不会给你所需的 id,因为没有一个通过,改变 chekbox 像这样:

    <Checkbox
        id={row.id}
        onChange={handleRowSelectionCheckboxClick}
        checked={idsOfSelectedRows.has(row.id)}
    />
    

    然后,像这样检索 ID:

    const idOfClickedRow = event.target.attributes.id.value;
    

    Updated codesandbox:


    像其他答案建议的那样,更改 handleRowSelectionCheckboxClick 函数调用,如示例中所示。 如果您喜欢使用匿名函数的解决方案,则应添加()onChange={() =&gt; handleRowSelectionCheckboxClick()}

    【讨论】:

      猜你喜欢
      • 2020-02-02
      • 1970-01-01
      • 2014-12-26
      • 2016-04-20
      • 1970-01-01
      • 2021-03-11
      • 1970-01-01
      • 2021-04-07
      • 2016-07-16
      相关资源
      最近更新 更多