【问题标题】:Child not rerendered when prop set with useState()使用 useState() 设置道具时未重新渲染子项
【发布时间】:2020-05-22 03:55:15
【问题描述】:

我有一种情况,我有父 (App) 和子 (MUIDatatable) 组件。孩子是一个数据表,它接受 columns 属性描述列结构以及为其中一个定义自定义渲染函数。在这个自定义渲染函数中,我创建了一个按钮实例,disabled 的状态应该取决于父级的状态,buttonsDisabled 值是通过 useState() 钩子设置的。到目前为止,它工作正常,但是当我还使用 useState() 更改 columns 道具时,更改 buttonsDisabled 值时不再触发重新渲染。代码如下所示:

  const App = () => {
  const [buttonsDisabled, setButtonsDisabled] = useState(false);

  const tableData = {
    columns: [
      { name: "name", label: "Name", options: {} },
      {
        name: "action",
        label: "Action",
        options: {
          customBodyRender: v => (
            <button disabled={buttonsDisabled}>button</button>
          )
        }
      }
    ],
    data: [["A", null], ["B", null], ["C", null], ["D", null]]
  };

  const btnOnClick = () => {
    setButtonsDisabled(true);
  };

  /***** discussed part of code *****/
  const [columns] = useState(tableData.columns); // if we use this, buttons are not disabled
  //const columns = tableData.columns; // if we use this, buttons are properly disabled
  /**********************************/

  return (
    <div>
      <button onClick={btnOnClick}>DISABLE BUTTONS</button>
      <MUIDataTable title="title" data={tableData.data} columns={columns} />
    </div>
  );
};

它也可以在代码沙箱中获得: https://codesandbox.io/s/muidatatables-custom-toolbar-cy4vg

我准备的代码是原始代码的精简版本,因此它可能没有多大意义,但它将代码限制在最低限度,以便能够重现问题。

我无法理解的是为什么使用useState 修改columns 值会阻止指定的customBodyRender 函数在buttonsDisabled 值更改时被触发,而通过简单的赋值设置它就可以了。毕竟在这两种情况下,它仍然是对同一个数组的引用。我相信这是我遗漏的一些简单概念,但如果能帮助我指出那是什么,我将不胜感激。

【问题讨论】:

    标签: javascript reactjs ecmascript-6 mui-datatable


    【解决方案1】:

    当您创建初始columns 状态时,您的customBodyRender 函数可以访问外部函数的buttonsDisabled 变量(请参阅:closure),默认为false。初始化后,您的 columns 变量将存储在您的状态中,customBodyRender 中的 buttonsDisabled 变量将继续从外部函数引用原始值。

    您是否可以将buttonsDisabled 传递给MUIDataTable 表组件,或者将其作为参数传递给customBodyRender 函数?

    customBodyRender: (v, disabled) => (
      <button disabled={disabled}>button</button>
    )
    

    【讨论】:

    • 请注意,如果您像在帖子中那样重新创建tableData.columnscustomBodyRender 可以直接在外部函数中访问buttonsDisabled 的最新值。
    猜你喜欢
    • 2020-03-12
    • 1970-01-01
    • 1970-01-01
    • 2020-01-13
    • 2022-01-02
    • 1970-01-01
    • 2020-01-20
    • 2018-01-30
    • 2018-12-28
    相关资源
    最近更新 更多