React Table-在表中隐藏行&重置按钮显示隐藏的行

发布于 2025-01-21 10:40:36 字数 1235 浏览 0 评论 0 原文

在我的列中 show 有一个 switch button( toggle 似乎在沙箱中不起作用,也许是因为 tailwindcss ? 我们也可能有可能再次切换,并且出现原始行(无灰色)。

表上方的可见度按钮将从所有表中删除灰色/禁用行(也无法正常工作)。以及一个重置全部的 visibilityOfficon 按钮(我们获取原始表)。

这里我做了什么,但是当我单击切换时,我会收到错误,所有表都被隐藏了:

export default function MenuDisplay() {
    const { menuId } = useParams();
    const { match } = JsonRules;
    const dataFindings = match.find((el) => el._id_menu === menuId)?._ids ?? [];
    const [disabled, setDisabled] = useState(false);

  const toggler_disabled = () => {
    disabled ? setDisabled(false) : setDisabled(true);
  };


    const data = useMemo(
        () => [
            //some headers ....    
            {
                Header: 'Show',
                accessor: (row) =>  
                  <Toggle  onClick ={toggler_disabled} value={disabled} onChange= 
                 {setDisabled} />
            }
        ],[]
    );
    ...
    return (
        {
            disabled?
                <Table 
                    data = { dataFindings }
                    columns = { data }
                />
            : null
        }
    );
}

In my column Show there is a switch button (Toggle doesn't seems working in sandbox, maybe because of tailwindcss? but it works in local...) when you click on it, it will turn the selected row into gray (as if the row is disabled but you can still view the content).
We may have also the possibility to switch again and the original row (without gray) appears.

The VisibilityIcon button above the table will remove from all the table the gray/disabled rows (not working either). And a VisibilityoffIcon button that resets all (we get the original table).

Here what I have done but when I click on the Toggle I get errors and all the table is hidden:

export default function MenuDisplay() {
    const { menuId } = useParams();
    const { match } = JsonRules;
    const dataFindings = match.find((el) => el._id_menu === menuId)?._ids ?? [];
    const [disabled, setDisabled] = useState(false);

  const toggler_disabled = () => {
    disabled ? setDisabled(false) : setDisabled(true);
  };


    const data = useMemo(
        () => [
            //some headers ....    
            {
                Header: 'Show',
                accessor: (row) =>  
                  <Toggle  onClick ={toggler_disabled} value={disabled} onChange= 
                 {setDisabled} />
            }
        ],[]
    );
    ...
    return (
        {
            disabled?
                <Table 
                    data = { dataFindings }
                    columns = { data }
                />
            : null
        }
    );
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

℉服软 2025-01-28 10:40:37

您正在在行数据下使用 usememo ,该行记录所有具有相同点击事件的行而无需依赖的行。如果要用更新的状态调用 usememo ,则可以以这种方式实现它

//`show` is your state
//`data` is your rows
useMemo(() => data, [show])

,第二个问题是您跟踪 show> show 状态,该状态仅是true/false值。如果您想具有多个行状态,则需要将其保留为数组。

这是带有一些说明的完整代码(您还可以检查此游乐场

import Table from "./Table";
import React, { useState, useMemo } from "react";
import JsonData from "./match.json";
import { useParams } from "react-router-dom";
import { Link } from "react-router-dom";
import VisibilityOffIcon from "@mui/icons-material/VisibilityOff";
import VisibilityIcon from "@mui/icons-material/Visibility";

export default function MenuDisplay() {
  const { menuId } = useParams();
  const { match } = JsonData;
  const [hiddenRows, setHiddenRows] = useState([]);

  const matchData = match.find((el) => el._id_menu === menuId)?._ids ?? [];

  //update hidden row list
  const updateHiddenRows = (rowId) => {
    if (hiddenRows.includes(rowId)) {
      //remove the current clicked row from the hidden row list
      setHiddenRows(hiddenRows.filter((row) => row !== rowId));
    } else {
      //add the current clicked row from the hidden row list
      setHiddenRows([...hiddenRows, rowId]);
    }
  };

  const data = useMemo(() => [
    {
      Header: "Name",
      accessor: (row) =>
        //check current row is in hidden rows or not
        !hiddenRows.includes(row._id) && (
          <Link to={{ pathname: `/menu/${menuId}/${row._id}` }}>
            {row.name}
          </Link>
        )
    },
    {
      Header: "Description",
      //check current row is in hidden rows or not
      accessor: (row) => !hiddenRows.includes(row._id) && row.description
    },
    {
      Header: "Dishes",
      //check current row is in hidden rows or not
      accessor: (row) => !hiddenRows.includes(row._id) && row.dishes,
      Cell: ({ value }) => value && Object.values(value[0]).join(", ")
    },
    {
      Header: "Show",
      accessor: (row) => (
        <button onClick={() => updateHiddenRows(row._id)}>
          {!hiddenRows.includes(row._id) ? (
            <VisibilityIcon>Show</VisibilityIcon>
          ) : (
            <VisibilityOffIcon>Show</VisibilityOffIcon>
          )}
        </button>
      )
    }
  ], [hiddenRows]);

  const initialState = {
    sortBy: [
      { desc: false, id: "id" },
      { desc: false, id: "description" },
      { desc: false, id: "dishes" }
    ]
  };

  return (
    <div>
      <Table
        data={matchData}
        columns={data}
        initialState={initialState}
        withCellBorder
        withRowBorder
        withSorting
        withPagination
      />
    </div>
  );
}

You're using useMemo under row data that memoize all rows which have the same click event without dependencies. If you want to call useMemo with an updated state, you can implement it this way

//`show` is your state
//`data` is your rows
useMemo(() => data, [show])

And the second problem is you track the show state which is only a true/false value. If you want to have multiple row states, you need to keep it as an array.

Here is the full code with some explanation (You also can check this playground)

import Table from "./Table";
import React, { useState, useMemo } from "react";
import JsonData from "./match.json";
import { useParams } from "react-router-dom";
import { Link } from "react-router-dom";
import VisibilityOffIcon from "@mui/icons-material/VisibilityOff";
import VisibilityIcon from "@mui/icons-material/Visibility";

export default function MenuDisplay() {
  const { menuId } = useParams();
  const { match } = JsonData;
  const [hiddenRows, setHiddenRows] = useState([]);

  const matchData = match.find((el) => el._id_menu === menuId)?._ids ?? [];

  //update hidden row list
  const updateHiddenRows = (rowId) => {
    if (hiddenRows.includes(rowId)) {
      //remove the current clicked row from the hidden row list
      setHiddenRows(hiddenRows.filter((row) => row !== rowId));
    } else {
      //add the current clicked row from the hidden row list
      setHiddenRows([...hiddenRows, rowId]);
    }
  };

  const data = useMemo(() => [
    {
      Header: "Name",
      accessor: (row) =>
        //check current row is in hidden rows or not
        !hiddenRows.includes(row._id) && (
          <Link to={{ pathname: `/menu/${menuId}/${row._id}` }}>
            {row.name}
          </Link>
        )
    },
    {
      Header: "Description",
      //check current row is in hidden rows or not
      accessor: (row) => !hiddenRows.includes(row._id) && row.description
    },
    {
      Header: "Dishes",
      //check current row is in hidden rows or not
      accessor: (row) => !hiddenRows.includes(row._id) && row.dishes,
      Cell: ({ value }) => value && Object.values(value[0]).join(", ")
    },
    {
      Header: "Show",
      accessor: (row) => (
        <button onClick={() => updateHiddenRows(row._id)}>
          {!hiddenRows.includes(row._id) ? (
            <VisibilityIcon>Show</VisibilityIcon>
          ) : (
            <VisibilityOffIcon>Show</VisibilityOffIcon>
          )}
        </button>
      )
    }
  ], [hiddenRows]);

  const initialState = {
    sortBy: [
      { desc: false, id: "id" },
      { desc: false, id: "description" },
      { desc: false, id: "dishes" }
    ]
  };

  return (
    <div>
      <Table
        data={matchData}
        columns={data}
        initialState={initialState}
        withCellBorder
        withRowBorder
        withSorting
        withPagination
      />
    </div>
  );
}
傲性难收 2025-01-28 10:40:37
  1. 保留选择的项目ID的地图,并通过切换组件切换这些值。
  2. 使用单独的状态进行切换按钮过滤所选项目。
  3. 实施行支架Getter。

示例:

menudisplay

function MenuDisplay() {
  const { menuId } = useParams();
  const { match } = JsonData;

  // toggle show/hide button
  const [hideSelected, setHideSelected] = useState(false);

  // select rows by item id
  const [selected, setSelected] = useState({});

  const rowSelectHandler = (id) => (checked) => {
    setSelected((selected) => ({
      ...selected,
      [id]: checked
    }));
  };

  const toggleShow = () => setHideSelected((hide) => !hide);

  const matchData = (
    match.find((el) => el._id_menu === menuId)?._ids ?? []
  ).filter(({ _id }) => {
    if (hideSelected) {
      return !selected[_id];
    }
    return true;
  });

  const getRowProps = (row) => {
    return {
      style: {
        backgroundColor: selected[row.values.id] ? "lightgrey" : "white"
      }
    };
  };

  const data = [
    {
      // add item id to row data
      Header: "id",
      accessor: (row) => row._id
    },
    {
      Header: "Name",
      accessor: (row) => (
        <Link to={{ pathname: `/menu/${menuId}/${row._id}` }}>{row.name}</Link>
      )
    },
    {
      Header: "Description",
      accessor: (row) => row.description
    },
    {
      Header: "Dishes",
      accessor: (row) => row.dishes,
      id: "dishes",
      Cell: ({ value }) => value && Object.values(value[0]).join(", ")
    },
    {
      Header: "Show",
      accessor: (row) => (
        <Toggle
          value={selected[row._id]}
          onChange={rowSelectHandler(row._id)}
        />
      )
    }
  ];

  const initialState = {
    sortBy: [
      { desc: false, id: "id" },
      { desc: false, id: "description" }
    ],
    hiddenColumns: ["dishes", "id"] // <-- hide id column too
  };

  return (
    <div>
      <button type="button" onClick={toggleShow}>
        {hideSelected ? <VisibilityOffIcon /> : <VisibilityIcon />}
      </button>

      <Table
        data={matchData}
        columns={data}
        initialState={initialState}
        withCellBorder
        withRowBorder
        withSorting
        withPagination
        rowProps={getRowProps} // <-- pass rowProps getter
      />
    </div>
  );
}

export default function Table({
  className,
  data,
  columns,
  initialState,
  withCellBorder,
  withRowBorder,
  withSorting,
  withPagination,
  withColumnSelect,
  rowProps = () => ({}) // <-- destructure row props getter
}) {
  ...

  return (
    <div className={className}>
      ...
      <div className="....">
        <table className="w-full" {...getTableProps()}>
          <thead className="....">
            ...
          </thead>
          <tbody {...getTableBodyProps()}>
            {(withPagination ? page : rows).map((row) => {
              prepareRow(row);
              return (
                <tr
                  className={....}
                  {...row.getRowProps(rowProps(row))} // <-- call row props getter
                >
                  ...
                </tr>
              );
            })}
          </tbody>
        </table>
      </div>
    </div>
  );
}

“编辑反应台式

”

  1. Keep a map of item ids that are selected and toggle these values via the Toggle component.
  2. Use separate state for the toggle button to filter the selected items.
  3. Implement a row props getter.

Example:

MenuDisplay

function MenuDisplay() {
  const { menuId } = useParams();
  const { match } = JsonData;

  // toggle show/hide button
  const [hideSelected, setHideSelected] = useState(false);

  // select rows by item id
  const [selected, setSelected] = useState({});

  const rowSelectHandler = (id) => (checked) => {
    setSelected((selected) => ({
      ...selected,
      [id]: checked
    }));
  };

  const toggleShow = () => setHideSelected((hide) => !hide);

  const matchData = (
    match.find((el) => el._id_menu === menuId)?._ids ?? []
  ).filter(({ _id }) => {
    if (hideSelected) {
      return !selected[_id];
    }
    return true;
  });

  const getRowProps = (row) => {
    return {
      style: {
        backgroundColor: selected[row.values.id] ? "lightgrey" : "white"
      }
    };
  };

  const data = [
    {
      // add item id to row data
      Header: "id",
      accessor: (row) => row._id
    },
    {
      Header: "Name",
      accessor: (row) => (
        <Link to={{ pathname: `/menu/${menuId}/${row._id}` }}>{row.name}</Link>
      )
    },
    {
      Header: "Description",
      accessor: (row) => row.description
    },
    {
      Header: "Dishes",
      accessor: (row) => row.dishes,
      id: "dishes",
      Cell: ({ value }) => value && Object.values(value[0]).join(", ")
    },
    {
      Header: "Show",
      accessor: (row) => (
        <Toggle
          value={selected[row._id]}
          onChange={rowSelectHandler(row._id)}
        />
      )
    }
  ];

  const initialState = {
    sortBy: [
      { desc: false, id: "id" },
      { desc: false, id: "description" }
    ],
    hiddenColumns: ["dishes", "id"] // <-- hide id column too
  };

  return (
    <div>
      <button type="button" onClick={toggleShow}>
        {hideSelected ? <VisibilityOffIcon /> : <VisibilityIcon />}
      </button>

      <Table
        data={matchData}
        columns={data}
        initialState={initialState}
        withCellBorder
        withRowBorder
        withSorting
        withPagination
        rowProps={getRowProps} // <-- pass rowProps getter
      />
    </div>
  );
}

Table

export default function Table({
  className,
  data,
  columns,
  initialState,
  withCellBorder,
  withRowBorder,
  withSorting,
  withPagination,
  withColumnSelect,
  rowProps = () => ({}) // <-- destructure row props getter
}) {
  ...

  return (
    <div className={className}>
      ...
      <div className="....">
        <table className="w-full" {...getTableProps()}>
          <thead className="....">
            ...
          </thead>
          <tbody {...getTableBodyProps()}>
            {(withPagination ? page : rows).map((row) => {
              prepareRow(row);
              return (
                <tr
                  className={....}
                  {...row.getRowProps(rowProps(row))} // <-- call row props getter
                >
                  ...
                </tr>
              );
            })}
          </tbody>
        </table>
      </div>
    </div>
  );
}

Edit react-table-hide-rows-in-table-reset-button-to-display-hidden-rows

enter image description here
enter image description here

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文