首页 > 解决方案 > 目标特定箭头以更改表格中的排序

问题描述

我正在创建一个使用箭头显示排序是升序还是降序的表格。问题是,当我单击一列上的箭头时,所有箭头都会移动。我想点击特定箭头的位置只会改变我点击的列的方向。我正在尝试将单击的箭头与 th 的键值的名称相匹配,我已经在这个逻辑上工作了一段时间,但似乎无法将其记下来。有人能指出我正确的方向吗

代码

const sortTable = (key) => {
        setSortDirection(!sortDirection);
        const clonedOptions = [...listOfOptions];
        clonedOptions.sort((a, b) => {
            return sortDirection ? a[key] - b[key] : b[key] - a[key];
        })
        console.log(key)
        setListOfOptions(clonedOptions);

        const arrows = document.querySelectorAll('.fas')
        arrows.forEach(arrow => {
            if (sortDirection === true) {
                arrow.classList.add('arrowup')
            } else if (sortDirection === false) {
                arrow.classList.remove('arrowup')
            }
        })
    }

 <table>
                    <thead>
                        <tr>
                            <th></th>
                            <th onClick={() => sortTable('clock')}>Date </th>
                            <th onClick={() => sortTable('name')}>Stock Name <span><i onClick={() => sortTable('name')} className="fas fa-sort-up"></i></span></th>
                            <th onClick={() => sortTable('price')}>Price Of Option <span><i onClick={() => sortTable('price')} className="fas fa-sort-up"></i></span></th>
                            <th onClick={() => sortTable('amountOfOptions')}>Number Of Options <span><i onClick={() => sortTable('amountOfOptions')} className="fas fa-sort-up"></i></span></th>
                            <th onClick={() => sortTable('totalAmountSpent')}>Total Amount Spent <span><i onClick={() => sortTable('totalAmountSpent')} className="fas fa-sort-up"></i></span></th>
                            <th onClick={() => sortTable('optionPriceSoldAt')}>Option Sold At <span><i onClick={() => sortTable('optionPriceSoldAt')} className="fas fa-sort-up"></i></span></th>
                            <th onClick={() => sortTable('amountOfOptionsSold')}>Options Sold <span><i onClick={() => sortTable('amountOfOptionsSold')} className="fas fa-sort-up"></i></span></th>
                            <th onClick={() => sortTable('totalProfit')}>Proft <span><i onClick={() => sortTable('totalProfit')} className="fas fa-sort-up"></i></span></th>
                        </tr>
                    </thead>
                    {listOfOptions.map((option) => {
                        return (
                            <tbody key={uuidv1()}>
                                <tr>
                                    <td title="delete" onClick={() => deleteOption(option.id)}><span className="delete">x</span></td>
                                    <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>

标签: javascriptreactjshtml-table

解决方案


首先,我建议您创建一个表头的硬编码对象,如下所示:

const tableHeaders = [{id: "clock", label: "Date"}, {id: "name", label: "Stock Name"}, ...] // and so on

一旦你明白了,你可以th用这个简化所有元素:

<thead>
  <tr>
    <th></th>
    {tableHeaders.map(({id, label}) => // destructuring value here
      <th key={id} onClick={() => sortTable(id)}>{label} <span><i onClick={() => sortTable(id)} className="fas fa-sort-up"></i></span></th>
  </tr>
</thead>

好的,但是现在有了您的问题,您不应该在几乎所有情况下都使用 vanilla js 来定位 DOM 中的元素以更改它们的类等。那么如何更改元素的 className 以做出动态反应?

用这个修改上面的代码:

<thead>
  <tr>
    <th></th>
    {tableHeaders.map(({id, label}) => // destructuring value here
      <th key={id} onClick={() => sortTable(id)}>{label} <span><i onClick={() => sortTable(id)} className={`fas fa-sort-up ${sortedColumns.includes(id) ? "arrowup" : ""`}></i></span></th>
  </tr>
</thead>

所以你没有sortedColumns定义,所以你需要一个状态,它是一个包含所有排序标题的 id 的数组。

const [sortedColumns, setSortedColumns] = useState([]) // no column sorted at first

最后,您应该修改sortTable以将已排序的列添加到数组中(或删除它们,又名。filter)。把它留给你:)


推荐阅读