简体   繁体   中英

Trying to sort data inside a react table: Reactjs

I am trying to sort the table data based on the field selected from the dropdown. It should alternatively sort between ascending or descending whenever the same field is clicked. I am maintaining a sort object that decides which field is selected and what is the sort order. Then it is sent to lodash orderBy with the field and the order. It does not work

This is what I have tried. Can some one tell me what I am doing wrong. Help is really appreciated.

https://codesandbox.io/s/simple-react-class-component-1n3f9?file=/src/index.js:0-3000

import React from "react";
import ReactDOM from "react-dom";
import "semantic-ui-css/semantic.min.css";
import { Dropdown } from "semantic-ui-react";
import moment from "moment";
import orderby from "lodash.orderby";

const options = [
  { key: 1, text: "Name", value: "name", icon: "sort" },
  { key: 2, text: "Time", value: "time", icon: "sort" },
  { key: 3, text: "Type", value: "type", icon: "sort" }
];

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      list: [],
      original: [],
      sortObject: { field: "", order: "" }
    };
  }

  componentDidMount() {
    let list = [
      {
        name: "namev1",
        time: 1583295463213,
        type: 14
      },
      {
        name: "namea2",
        time: 1582885423296,
        type: 15
      },
      {
        name: "namea3",
        time: 1581295463213,
        type: 16
      }
    ];
    this.setState({ list, original: list });
  }

  handleSearch = e => {
    let searchInput = e.target.value;
    let filteredData = this.state.original.filter(value => {
      return (
        value.name.toLowerCase().includes(searchInput.toLowerCase()) ||
        value.type.toString().includes(searchInput.toString())
      );
    });
    this.setState({ list: filteredData });
  };

  formSortObject = fieldName => {
    let { sortObject } = this.state;
    if (!sortObject.field || sortObject.field !== fieldName) {
      Object.assign(sortObject, {
        field: fieldName,
        order: "asc"
      });
      return sortObject;
    } else if (sortObject.field === fieldName) {
      Object.assign(sortObject, {
        ...sortObject,
        order: sortObject.order === "desc" ? "asc" : "desc"
      });
      return sortObject;
    }
  };

  handleSort = (e, data) => {
    let dropdDownValue = data.value;
    let currentField = this.formSortObject(dropdDownValue);
    let result = orderby(
      this.state.list,
      currentField.field,
      currentField.order
    );
    this.setState({ list: result });
  };

  render() {
    return (
      <>
        Search: <input type="text" onChange={this.handleSearch} />
        <Dropdown text="Sort By" options={options} onChange={this.handleSort} />
        <h1>List</h1>
        <table>
          <tbody>
            {this.state.list.map((item, index) => (
              <tr key={index}>
                <td>
                  <p>{index + 1}</p>
                </td>
                <td>
                  <p>{item.name}</p>
                </td>
                <td>
                  <p>{moment().diff(item.time, "days")}</p>
                </td>
                <td>
                  <p>{item.type}</p>
                </td>
              </tr>
            ))}
          </tbody>
        </table>
      </>
    );
  }
}

Your code isnt's working as you spected because you are calling the handleSort function only when the value of the select change (see the onChange of your <Dropdown /> ).

What you need is the function executed when an option is clicked.

I searched for the documentation of the library you are using and I came to the conclusion that what you need is this.

    <Dropdown text='Sort By'>
        <Dropdown.Menu>
          {options.map(item=>
            <Dropdown.Item text={item.text} value={item.value} icon={item.icon} key={item.key} onClick={this.handleSort}/>
          )}
        </Dropdown.Menu>
    </Dropdown>

I tried it in your codesandbox and it works perfectly!

I hope it helps!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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