使用远程数据时无法在 Material Table header 中更改状态

Can't change state in Material Table header when using remote data

我在自定义 header 上放置了一个简单的布尔状态,计划是让这个状态控制一个下拉菜单。我在这个自定义 header 上使用了一个简单的 onClick,它将状态设置为相反的值,然后记录状态。 但是状态保持不变,每次点击都不会改变。

当我使用初始 setState 设置列时会发生这种情况,因为我需要 table 完全基于服务器端。当使用普通设置列时,它可以工作,但这不是特别需要。

header高亮显示,点击它,你会在控制台看到状态日志。

export default function PositioningActionsColumn() {
  const [stateData, setStateData] = useState([]);
  const [stateColumns, setStateColumns] = useState([]);
  const [isOpen, setIsOpen] = useState(false);

  // setting the columns and data - will be from a fetch later
  useEffect(() => {
    setStateColumns([
      {
        title: nameHeader,
        field: "name"
      },
      {
        title: "Surname",
        field: "surname",
        initialEditValue: "initial edit value"
      },
      { title: "Birth Year", field: "birthYear", type: "numeric" },
      {
        title: "Birth Place",
        field: "birthCity",
        lookup: { 34: "İstanbul", 63: "Şanlıurfa" }
      }
    ]);
    setStateData([
      { name: "Mehmet", surname: "Baran", birthYear: 1987, birthCity: 63 },
      { name: "Zerya Betül", surname: "Baran", birthYear: 2017, birthCity: 34 }
    ]);
  }, []);

  const orderFunc = (orderedColumnId, orderDirection) => {
    console.log(
      "orderedColumnId:",
      orderedColumnId,
      "orderDirection:",
      orderDirection
    );
  };

  const searchFunc = e => {
    console.log(e);
  };

  const handleClick = () => {
    setIsOpen(!isOpen);
    console.log(isOpen);
  };

  const nameHeader = (
    <div style={{ background: "lightblue" }} onClick={handleClick}>
      Click on this custom Name Header
    </div>
  );

  return (
    <MaterialTable
      title="Editable Preview"
      icons={tableIcons}
      columns={stateColumns}
      data={stateData}
      onOrderChange={(orderedColumnId, orderDirection) => {
        orderFunc(orderedColumnId, orderDirection);
      }}
      onSearchChange={e => searchFunc(e)}
      options={{ draggable: false, selection: true, actionsColumnIndex: -1 }}
      actions={[
        {
          tooltip: "Remove All Selected Users",
          icon: "delete",
          onClick: (evt, data) => {
            console.log({ data });
            alert("You want to delete " + data.length + " rows");
          }
        },
        {
          isFreeAction: true,
          tooltip: "FreeAction",
          icon: () => <div>Free</div>,
          onClick: (evt, data) => {
            console.log({ data });
          }
        }
      ]}
      editable={{
        onRowAdd: newData =>
          new Promise((resolve, reject) => {
            setTimeout(() => {
              {
                console.log({ newData });
                const data = stateData;
                data.push(newData);
                setStateData(data, () => resolve());
              }
              resolve();
            }, 1000);
          }),
        onRowUpdate: (newData, oldData) =>
          new Promise((resolve, reject) => {
            setTimeout(() => {
              {
                console.log({ newData }, { oldData });
                const data = stateData;
                const index = data.indexOf(oldData);
                data[index] = newData;
                setStateData(data, () => resolve());
              }
              resolve();
            }, 1000);
          }),
        onRowDelete: oldData =>
          new Promise((resolve, reject) => {
            setTimeout(() => {
              {
                console.log({ oldData });
                let data = stateData;
                const index = data.indexOf(oldData);
                data.splice(index, 1);
                setStateData(data, () => resolve());
              }
              resolve();
            }, 1000);
          })
      }}
    />
  );
}

https://codesandbox.io/s/material-table-testing-actions-position-and-output-2-sj1tt

将您对 setIsOpen 的调用更改为:

const handleClick = useCallback(() => setIsOpen(current => !current), []);

它将解决该问题。但仍然不建议将反应元素存储在状态中。它应该只包含用于呈现实际元素的纯数据。