简体   繁体   English

如何在 React 中对 HTML 表格进行排序?

[英]How to sort an HTML table in React?

I have a table that contains numbers, dates, and strings.我有一个包含数字、日期和字符串的表。 I want to be able to sort them by clicking on the table's headings and have them sort by the particular clicked on heading, but I am having trouble with the logic to do this.我希望能够通过单击表格的标题对它们进行排序,并让它们按特定单击的标题进行排序,但是我在执行此操作的逻辑上遇到了问题。 I have read other stack overflow answers but they are somewhat confusing as to what I am supposed to do.我已经阅读了其他堆栈溢出的答案,但它们对我应该做什么有些困惑。 Can someone point me in the right direction?有人可以指出我正确的方向吗?

Function 

 const sorted = () => {
        const arr = []
        const tableBody = document.getElementsByTagName('table')
        const tableRow = document.getElementsByTagName('tr')
        const tableHeader = document.querySelectorAll('th');
        console.log(tableBody)

        for (let i = 0; i < tableHeader.length; i++) {
            tableHeader[i].addEventListener('click', () => {
                console.log(tableBody)
            })
        }

    }
    sorted()

Table

 <div className="outputs" >
                <table>
                    <tr>
                        <th>Date</th>
                        <th>Stock Name</th>
                        <th>Price Of Option</th>
                        <th>Number Of Options</th>
                        <th>Total Amount Spent</th>
                        <th>Option Sold At</th>
                        <th>Amount Of Options Sold</th>
                        <th>Proft</th>
                    </tr>
                    {listOfOptions.map(option => {
                        return (
                            <tbody>
                                <tr>
                                    <td>{option.clock}</td>
                                    <td>{option.name.toUpperCase()}</td>
                                    <td>${option.price}</td>
                                    <td>{option.amountOfOptions}</td>
                                    <td>${option.totalAmountSpent.toFixed(2)}</td>
                                    <td>${option.optionPriceSoldAt}</td>
                                    <td>{option.amountOfOptionsSold}</td>
                                    <td style={{ color: option.totalProfit >= 0 ? 'green' : 'red' }}>${option.totalProfit.toFixed(2)}</td>
                                </tr>
                            </tbody>
                        )
                    })}
                </table>
            </div>

As I can see it -正如我所见——

  • add handler on each or one that wrapps all在每个或一个包装所有内容上添加处理程序
  • in handler get name of column and sort listOfOptions by this name (before it, map column name to key, ex: Price Of Option -> price, etc...)在处理程序中获取列名并按此名称对 listOfOptions 进行排序(在它之前,将列名映射到键,例如:选项的价格 -> 价格等...)
  • use hooks (useState) or setState to set new sortedArray to state and rerender component使用钩子 (useState) 或 setState 将新的 sortedArray 设置为 state 并重新渲染组件

The steps to take are:采取的步骤是:

  1. Store the array in a local variable listOfOptions将数组存储在局部变量listOfOptions
  2. Attach click handlers to the header elements of the table将点击处理程序附加到表格的标题元素
  3. Within these handlers, sort the arrays and replace the old array with the new sorted arrays.在这些处理程序中,对数组进行排序并用新的排序数组替换旧数组。

I have only implemented two header click handlers, but it should be enough to get the general idea.我只实现了两个标题单击处理程序,但应该足以了解总体思路。

import React, { useState } from "react";


export default function App() {
  const [listOfOptions, setListOfOptions] = useState([
    {
      clock: "23/12/2020",
      name: "Dorothy",
      price: 12.34,
      amountOfOptions: 1,
      totalAmountSpent: 23.3232,
      optionPriceSoldAt: 34.22323,
      amountOfOptionsSold: 122.34,
      totalProfit: 44433.343
    },
    {
      clock: "23/12/2020",
      name: "Brian",
      price: 12.34,
      amountOfOptions: 2,
      totalAmountSpent: 255.3232,
      optionPriceSoldAt: 52.194323,
      amountOfOptionsSold: 622.34,
      totalProfit: 9433.343
    },
    {
      clock: "23/12/2020",
      name: "Alfred",
      price: 12.34,
      amountOfOptions: 3,
      totalAmountSpent: 123.3232,
      optionPriceSoldAt: 12.22323,
      amountOfOptionsSold: 72.34,
      totalProfit: 5433.343
    }
  ]);

  function sortByNumberOfOptions() {
    const clonedOptions = [...listOfOptions];

    clonedOptions.sort((a, b) => {
      return a.amountOfOptions  - b.amountOfOptions;
    });

    setListOfOptions(clonedOptions);
  }

  function sortByName() {
    const clonedOptions = [...listOfOptions];

    clonedOptions.sort((a, b) => {
      if (a.name > b.name) {
        return 1;
      } else if (a.name < b.name) {
        return -1;
      }
      return 0;
    });

    setListOfOptions(clonedOptions);
  }

  return (
    <div>
      <div className="outputs">
        <table>
          <tr>
            <th>Date</th>
            <th onClick={sortByName}>Stock Name</th>
            <th>Price Of Option</th>
            <th onClick={sortByNumberOfOptions}>Number Of Options</th>
            <th>Total Amount Spent</th>
            <th>Option Sold At</th>
            <th>Amount Of Options Sold</th>
            <th>Proft</th>
          </tr>

          <tbody>
            {listOfOptions.map((option, index) => {
              return (
                <tr key={index}>
                  <td>{option.clock}</td>
                  <td>{option.name.toUpperCase()}</td>
                  <td>${option.price}</td>
                  <td>{option.amountOfOptions}</td>
                  <td>${option.totalAmountSpent.toFixed(2)}</td>
                  <td>${option.optionPriceSoldAt}</td>
                  <td>{option.amountOfOptionsSold}</td>
                  <td
                    style={{ color: option.totalProfit >= 0 ? "green" : "red" }}
                  >
                    ${option.totalProfit.toFixed(2)}
                  </td>
                </tr>
              );
            })}
          </tbody>
        </table>
      </div>
    </div>
  );
}


StackBlitz version here StackBlitz 版本在这里

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM