【问题标题】:React - Sorting Table Columns Inside a Map() MethodReact - 在 Map() 方法中对表列进行排序
【发布时间】:2021-04-05 23:22:15
【问题描述】:

当我的表头数据放在 .map() 方法中时,我正在尝试对表进行排序(升序/降序)(请参阅本文中代码框链接的第 73 行)。

我可以让手形表情符号更改 onClick,但没有进行排序。我认为这可能与将对象传递给 map 方法有关,而不是在我基于此功能的代码框中找到的单个字符串或数值。这是我要建模的原始沙箱: https://codesandbox.io/embed/table-sorting-example-ur2z9?fontsize=14&hidenavigation=1&theme=dark

...这是我的代码框,其中包含我需要排序的数据结构: https://codesandbox.io/s/table-sorting-example-forked-dofhj?file=/src/App.js

为了使每一列都可排序,我可以进行哪些更改?任何帮助/建议将不胜感激。

App.js

import React from "react";
import "./styles.css";
import {
  Button,
  Table,
  Thead,
  Tbody,
  Flex,
  Tooltip,
  Tr,
  Th,
  Td
} from "@chakra-ui/react";

//Table Headers
const TABLE_HEADERS = [
  { name: "ID Number" },
  { name: "User Type" },
  { name: "User Category" },
  { name: "User Interest" }
];

const useSortableData = (items, config = null) => {
  const [sortConfig, setSortConfig] = React.useState(config);

  const sortedItems = React.useMemo(() => {
    let sortableItems = [...items];
    if (sortConfig !== null) {
      sortableItems.sort((a, b) => {
        if (a[sortConfig.key] < b[sortConfig.key]) {
          return sortConfig.direction === "ascending" ? -1 : 1;
        }
        if (a[sortConfig.key] > b[sortConfig.key]) {
          return sortConfig.direction === "ascending" ? 1 : -1;
        }
        return 0;
      });
    }
    return sortableItems;
  }, [items, sortConfig]);

  const requestSort = (key) => {
    let direction = "ascending";
    if (
      sortConfig &&
      sortConfig.key === key &&
      sortConfig.direction === "ascending"
    ) {
      direction = "descending";
    }
    setSortConfig({ key, direction });
  };

  return { items: sortedItems, requestSort, sortConfig };
};

const ProductTable = (props) => {
  const { items, requestSort, sortConfig } = useSortableData(
    props.myUserErrorTypes
  );

  const getClassNamesFor = (name) => {
    if (!sortConfig) {
      return;
    }
    return sortConfig.key === name ? sortConfig.direction : undefined;
  };
  return (
    <Table>
      <caption>User Error Types</caption>
      <Thead>
        <Tr>
          {TABLE_HEADERS.map(({ name, description, isNumeric }) => (
            <Th key={name} isNumeric={isNumeric}>
              <Button
                type="button"
                onClick={() => requestSort(name)}
                className={getClassNamesFor(name)}
              >
                <Tooltip label={description} aria-label={description}>
                  {name}
                </Tooltip>
              </Button>
            </Th>
          ))}
        </Tr>
      </Thead>
      <Tbody>
        {items.map((error) => {
          const { userNumber, userType, errorId, errorCategory } = error;
          return (
            <React.Fragment key={errorId}>
              <Tr id={errorId} key={errorId}>
                <Td>{userNumber}</Td>
                <Td>{userType}</Td>
                <Td>{errorId}</Td>
                <Td>{errorCategory}</Td>
                <Td textAlign="center">
                  <Flex justify="justifyContent"></Flex>
                </Td>
              </Tr>
            </React.Fragment>
          );
        })}
      </Tbody>
    </Table>
  );
};

export default function App() {
  return (
    <div className="App">
      <ProductTable
        myUserErrorTypes={[
          {
            userNumber: 1234567890,
            userType: "SuperUser",
            errorId: 406,
            errorCategory: "In-Progress"
          },
          {
            userNumber: 4859687937,
            userType: "NewUser",
            errorId: 333,
            errorCategory: "Complete"
          }
        ]}
      />
    </div>
  );
}

【问题讨论】:

    标签: javascript reactjs sorting chakra-ui


    【解决方案1】:

    项目按表头名称排序(例如'ID Number'),因为您使用名称调用requestSort。将id 属性添加到TABLE_HEADERS 数组中与数据对象中的属性名称匹配的对象(例如userNumber),并将其作为参数传递给requestSortgetClassNamesFor 函数。

    const TABLE_HEADERS = [
      { name: 'ID Number', id: 'userNumber' },
      { name: 'User Type', id: 'userType' },
      { name: 'User Category', id: 'errorId' },
      { name: 'User Interest', id: 'errorCategory' },
    ]
    
    {
      TABLE_HEADERS.map(({ name, id }) => (
        <Th key={id}>
          <Button
            type="button"
            onClick={() => requestSort(id)}
            className={getClassNamesFor(id)}
          >
            {name}
          </Button>
        </Th>
      ))
    }
    

    您还尝试使用标头对象中的descriptionisNumeric 值,但它们都是undefined。您可能希望将这些属性添加到 TABLE_HEADERS 数组中的对象。

    【讨论】:

    • 谢谢 - 这行得通 - 但是如果我的 TABLE_HEADERS 是从服务器异步传入的,并且他们没有 'id' 键怎么办?
    • @Jon 从 API 获得数据和表头后,您可以使用 Array.prototype.map 将 id 属性添加到表头中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-08-09
    • 1970-01-01
    • 2014-03-03
    • 1970-01-01
    • 2017-09-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多