Как отсортировать таблицу по c и по полям des c в React js - PullRequest
1 голос
/ 23 января 2020

Я создаю простое приложение в ReactJS, которое работает с массивом JSON, вызывая определенный API. Затем я заполняю результаты массива в таблице. Теперь я хотел сделать столбцы таблицы сортируемыми. В идеале я хочу иметь сортировку как по возрастанию, так и по убыванию. Как только я щелкаю по заголовку, когда он сортируется по возрастанию, он должен сортировать по убыванию, и наоборот. Но проблема в том, что он работает только один раз и не работает как в порядке c, так и в порядке c, так как это сделать в как c, так и des c. Вот мой код.

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;

А вот ссылка на кодовый ящик моего кода. https://codesandbox.io/s/pensive-mountain-i259j

Ответы [ 2 ]

1 голос
/ 23 января 2020

Вы написали одинаковые функции сортировки как для восходящих, так и для дес c, в то время как они должны возвращать разные типы в обоих случаях.

без сохранения дополнительного флага, я исправил это. Проверьте это Посетите https://codesandbox.io/s/pensive-engelbart-i6n2y

1 голос
/ 23 января 2020

Вам нужно добавить направление к вашей функции сравнения и использовать его, чтобы изменить результаты следующим образом:

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>

Этот флаг также можно использовать для переключения класса на знак стрелки, указывающий порядок сортировки в заголовке столбца. .

Возможно, я неправильно понял направление Восходящего / Нисходящего, но я надеюсь, что вы поймете мой дрейф

...