Как сделать сортировку столбца через onClick React js?

Мне нужно отсортировать 2 столбца.

  1. ID(1-200)
  2. Title(A-Z)

Как мне это сделать с помощью onClick?

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

Буду благодарен любой помощи.

// Home.js
import React from "react";
import "./Home.css";
import { Link } from "react-router-dom";

export default class Home extends React.Component {
  // Constructor
  constructor(props) {
    super(props);

    this.state = {
      sortItemsTitle: [],
      sortItemsID: [],
      items: [],
    };
  }

  componentDidMount = () => {
    this.apiFetch();
  };

  //Fetch data from API
  apiFetch = () => {
    return fetch("https://jsonplaceholder.typicode.com/todos")
    .then((res) => res.json())
    .then((json) => {
      this.setState({
        items: json,
      });
    });
  };

  // Sort Title (A-Z)
  setSortedItemsTitle = () => {
    // const sorted = items.sort((a, b) => a.title.localeCompare(b.title));
    const { items } = this.state;
    const sortedTitle = items.sort((a,b) => {
      if (a.title < b.title) {
        return -1;
      }
      if (a.title > b.title) {
        return 1;
      }
      return 0;
    })
    console.log(sortedTitle);
  };
  
  // Sort ID (1-200)
  setSortedItemsID = () => {
    const { items } = this.state;
    const sortedID = items.sort((a, b) => {
      if (a.id < b.id) {
        return items.direction === 'ascending' ? -1 : 1;
      }
      if (a.id > b.id) {
        return items.direction === 'ascending' ? 1 : -1;
      }
      return 0;
    })
    console.log(sortedID);
  };

  render() {
    const { items } = this.state;
    return (
      <div>
        <h1>Home Page</h1>
        <table>
          <thead>
            <tr>
              <th>View Normal</th>
              <th>Group By UserID</th>
            </tr>
          </thead>
          <thead>
            <tr>
              <th>
                ID
                <button type="button" onClick={() => this.setSortedItemsID()}>⬇️</button>
                </th>
              <th>
                User ID
                </th>
              <th>
                Title
                <button type="button" onClick={() => this.setSortedItemsTitle()}>⬇️</button>
                </th>
              <th>
                Action
              </th>
            </tr>
          </thead>
          <tbody>
            {items.map((item) => (
              <tr key={item.id + item.title}>
                <td>{item.id}</td>
                <td>{item.userId}</td>
                <td>{item.title}</td>
                <td>
                  <Link target="self" to={`/details/${item.id}`}>
                    View Details
                  </Link>
                </td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    );
  }
}

Ответы (1 шт):

Автор решения: Oliver Patterson

Я не знаю как правильно работать с таким стейтом, но предпологаю так:

// Home.js
import React from "react";
import "./Home.css";
import { Link } from "react-router-dom";

export default class Home extends React.Component
{
    // Constructor
    constructor(props)
    {
        super(props);

        this.state = {
            items: []
        };
    }

    componentDidMount = () =>
    {
        this.apiFetch();
    };

    //Fetch data from API
    apiFetch = () =>
    {
        return fetch("https://jsonplaceholder.typicode.com/todos")
            .then((res) => res.json())
            .then((json) =>
            {
                this.setState((prevState) =>
                {
                    return { ...prevState, items: json };
                });
            });
    };

    // Sort Title (A-Z)
    setSortedItemsTitle = () =>
    {
        // const sorted = items.sort((a, b) => a.title.localeCompare(b.title));
        const { items } = this.state;
        const sortedTitle = items.sort((a, b) =>
        {
            if (a.title < b.title)
            {
                return -1;
            }
            if (a.title > b.title)
            {
                return 1;
            }
            return 0;
        });
        console.log(sortedTitle);

        this.setState((prevState) =>
        {
            return { ...prevState, items: sortedTitle };
        });
    };

    // Sort ID (1-200)
    setSortedItemsID = () =>
    {
        const { items } = this.state;
        const sortedID = items.sort((a, b) =>
        {
            if (a.id < b.id)
            {
                return items.direction === 'ascending' ? -1 : 1;
            }
            if (a.id > b.id)
            {
                return items.direction === 'ascending' ? 1 : -1;
            }
            return 0;
        });
        console.log(sortedID);

        this.setState((prevState) =>
        {
            return { ...prevState, items: sortedID };
        });
    };

    render()
    {
        const { items } = this.state;
        return (
            <div>
                <h1>Home Page</h1>
                <table>
                    <thead>
                        <tr>
                            <th>View Normal</th>
                            <th>Group By UserID</th>
                        </tr>
                    </thead>
                    <thead>
                        <tr>
                            <th>
                                ID
                                <button type="button" onClick={() => this.setSortedItemsID()}>⬇️</button>
                            </th>
                            <th>
                                User ID
                            </th>
                            <th>
                                Title
                                <button type="button" onClick={() => this.setSortedItemsTitle()}>⬇️</button>
                            </th>
                            <th>
                                Action
                            </th>
                        </tr>
                    </thead>
                    <tbody>
                        {items.map((item) => (
                            <tr key={item.id + item.title}>
                                <td>{item.id}</td>
                                <td>{item.userId}</td>
                                <td>{item.title}</td>
                                <td>
                                    <Link target="self" to={`/details/${ item.id }`}>
                                        View Details
                                    </Link>
                                </td>
                            </tr>
                        ))}
                    </tbody>
                </table>
            </div>
        );
    }
}

→ Ссылка