如何在 React js 中按 asc 和 desc 所有字段对 table 进行排序
How to sort table by asc and desc all field in React js
我正在 ReactJS 中构建一个简单的应用程序,它通过调用某个 API 来处理 JSON 数组。然后我将数组的结果填充到 table 中。我现在想制作 table sortable 的列。我最理想的是同时进行升序和降序排序。一旦我点击 header 当它按升序排序时,它应该按降序排序 vice-versa。但问题是它只工作一次,不像 asc 和 desc 顺序那样工作所以如何做到这一点升序和降序。这是我的代码。
import React, { Component } from "react";
import "./styles.css";
class App extends Component {
constructor(props) {
super(props);
this.state = {
driver: []
};
}
async componentDidMount() {
try {
const res = await fetch(`https://digitalfleet.eu/api/1/drivers/`);
const driver = await res.json();
console.log(driver);
this.setState({
driver
});
} catch (e) {
console.log(e);
}
}
compareBy(key) {
return function (a, b) {
if (a[key] < b[key]) return -1;
if (a[key] > b[key]) return 1;
return 0;
};
}
sortBy(key) {
let arrayCopy = [...this.state.driver ];
arrayCopy.sort(this.compareBy(key));
this.setState({driver: arrayCopy});
}
render() {
const { driver } = this.state;
return (
<div className="App">
<table className="table table-hover">
<thead>
<tr className="th ">
<th style={{ width: "5%" }}>id</th>
<th>Name</th>
<th className="">Car</th>
<th className="" onClick={() => this.sortBy('milage')}>Milage </th>
<th className="">Fuel Consumed</th>
<th className="">Average Fuel</th>
<th className="" onClick={() => this.sortBy('overspeeding_distance')}>Overspeeding Distance</th>
<th onClick={() => this.sortBy('critical_overspeed')}>Critical Speed</th>
<th onClick={() => this.sortBy('overallscore')}>Score</th>
</tr>
</thead>
<tbody>
{/* currPage.data */}
{driver.map((c, i) => (
<tr key={c.pk}>
<td>{i + 1}</td>
<td style={{ color: "#b71c1c" }} className="font-weight-bolder">
{c.name ? `${c.name}` : " ? "}
{/* </a> */}
</td>
<td>{c.carquanttity ? `${c.carquanttity}` : "-"} </td>
<td>{c.milage ? `${c.milage.toFixed(1)}` : "-"} </td>
<td>
{c.fuel_consumed ? `${c.fuel_consumed.toFixed(1)}` : "-"}
</td>
<td>
{c.average_fuel_consumed
? `${c.average_fuel_consumed.toFixed(1)}`
: "-"}{" "}
</td>
<td>
{c.overspeeding_distance
? `${c.overspeeding_distance.toFixed(1)}`
: "-"}
</td>
<td>
{c.critical_overspeed
? `${c.critical_overspeed.toFixed(1)}`
: "-"}
</td>
<td>
{c.overallscore ? `${c.overallscore.toFixed(1)}` : " - "}
</td>
</tr>
))}
</tbody>
</table>
</div>
);
}
}
export default App;
这是我的代码的 codesanbox link。 https://codesandbox.io/s/pensive-mountain-i259j
您需要为您的比较函数添加一个方向,并使用它来反转结果,如下所示:
compareBy(key, ascending) {
let reverse = ascending ? 1 : -1;
return function (a, b) {
if (a[key] < b[key]) return -1 * reverse;
if (a[key] > b[key]) return 1 * reverse;
return 0;
};
}
现在,您必须为要作为排序依据的每一行保留一个布尔值,并在每次点击时切换它(将 true 变为 false,反之亦然)
<th className="" onClick={() => {this.milageAsc = !this.milageAsc; this.sortBy('milage', this.milageAsc)}}>Milage </th>
该标志还可用于将 class 切换为指示列 header...
上的排序顺序的箭头符号
我可能弄错了升序/降序方向,但我希望你明白我的意思
您为升序和降序编写了相同的排序功能,但在这两种情况下它应该 return 不同的类型。
在不维护额外标志的情况下,我修复了它。检查一下
访问 https://codesandbox.io/s/pensive-engelbart-i6n2y
我正在 ReactJS 中构建一个简单的应用程序,它通过调用某个 API 来处理 JSON 数组。然后我将数组的结果填充到 table 中。我现在想制作 table sortable 的列。我最理想的是同时进行升序和降序排序。一旦我点击 header 当它按升序排序时,它应该按降序排序 vice-versa。但问题是它只工作一次,不像 asc 和 desc 顺序那样工作所以如何做到这一点升序和降序。这是我的代码。
import React, { Component } from "react";
import "./styles.css";
class App extends Component {
constructor(props) {
super(props);
this.state = {
driver: []
};
}
async componentDidMount() {
try {
const res = await fetch(`https://digitalfleet.eu/api/1/drivers/`);
const driver = await res.json();
console.log(driver);
this.setState({
driver
});
} catch (e) {
console.log(e);
}
}
compareBy(key) {
return function (a, b) {
if (a[key] < b[key]) return -1;
if (a[key] > b[key]) return 1;
return 0;
};
}
sortBy(key) {
let arrayCopy = [...this.state.driver ];
arrayCopy.sort(this.compareBy(key));
this.setState({driver: arrayCopy});
}
render() {
const { driver } = this.state;
return (
<div className="App">
<table className="table table-hover">
<thead>
<tr className="th ">
<th style={{ width: "5%" }}>id</th>
<th>Name</th>
<th className="">Car</th>
<th className="" onClick={() => this.sortBy('milage')}>Milage </th>
<th className="">Fuel Consumed</th>
<th className="">Average Fuel</th>
<th className="" onClick={() => this.sortBy('overspeeding_distance')}>Overspeeding Distance</th>
<th onClick={() => this.sortBy('critical_overspeed')}>Critical Speed</th>
<th onClick={() => this.sortBy('overallscore')}>Score</th>
</tr>
</thead>
<tbody>
{/* currPage.data */}
{driver.map((c, i) => (
<tr key={c.pk}>
<td>{i + 1}</td>
<td style={{ color: "#b71c1c" }} className="font-weight-bolder">
{c.name ? `${c.name}` : " ? "}
{/* </a> */}
</td>
<td>{c.carquanttity ? `${c.carquanttity}` : "-"} </td>
<td>{c.milage ? `${c.milage.toFixed(1)}` : "-"} </td>
<td>
{c.fuel_consumed ? `${c.fuel_consumed.toFixed(1)}` : "-"}
</td>
<td>
{c.average_fuel_consumed
? `${c.average_fuel_consumed.toFixed(1)}`
: "-"}{" "}
</td>
<td>
{c.overspeeding_distance
? `${c.overspeeding_distance.toFixed(1)}`
: "-"}
</td>
<td>
{c.critical_overspeed
? `${c.critical_overspeed.toFixed(1)}`
: "-"}
</td>
<td>
{c.overallscore ? `${c.overallscore.toFixed(1)}` : " - "}
</td>
</tr>
))}
</tbody>
</table>
</div>
);
}
}
export default App;
这是我的代码的 codesanbox link。 https://codesandbox.io/s/pensive-mountain-i259j
您需要为您的比较函数添加一个方向,并使用它来反转结果,如下所示:
compareBy(key, ascending) {
let reverse = ascending ? 1 : -1;
return function (a, b) {
if (a[key] < b[key]) return -1 * reverse;
if (a[key] > b[key]) return 1 * reverse;
return 0;
};
}
现在,您必须为要作为排序依据的每一行保留一个布尔值,并在每次点击时切换它(将 true 变为 false,反之亦然)
<th className="" onClick={() => {this.milageAsc = !this.milageAsc; this.sortBy('milage', this.milageAsc)}}>Milage </th>
该标志还可用于将 class 切换为指示列 header...
上的排序顺序的箭头符号我可能弄错了升序/降序方向,但我希望你明白我的意思
您为升序和降序编写了相同的排序功能,但在这两种情况下它应该 return 不同的类型。
在不维护额外标志的情况下,我修复了它。检查一下 访问 https://codesandbox.io/s/pensive-engelbart-i6n2y