Toggle ascending and Toggle descending in React Hooks

Asked
Active3 hr before
Viewed126 times

4 Answers

ascendingdescendinghooksreacttoggle
90%

You can use data to store sorted data and the toggle is boolean to store sstate of the toggle:, if toggle is either true or false, setToggle(result) is not correct; it should be setToggle(toggle => !toggle). – secan Jul 14 at 10:23 ,I have a toggle button. When I click on the button, I was it to sort in ascending order, and when I click a second time I want to to sort into descending order. I can not get it do either.... not sure what it could be.,Connect and share knowledge within a single location that is structured and easy to search.

You can use data to store sorted data and the toggle is boolean to store sstate of the toggle:

const toggleTime = () => {
   const newToggle = !toggle;
   setToggle(newToggle);
   setData((preData) =>
      preData.sort((a, b) => {
         return newToggle ?
            a.order.deadline - b.order.deadline :
            b.order.deadline - a.order.deadline;
      })
   );
};
88%

Search Answer Titles

import React from 'react';
import './styles.css';

const useSortableData = (items, config = null) => {
  const [sortConfig, setSortConfig] = React.useState(config);

  const sortedItems = React.useMemo(() => {
    let sortableItems = [...items];
    if (sortConfig !== null) {
      sortableItems.sort((a, b) => {
        if (a[sortConfig.key] < b[sortConfig.key]) {
          return sortConfig.direction === 'ascending' ? -1 : 1;
        }
        if (a[sortConfig.key] > b[sortConfig.key]) {
          return sortConfig.direction === 'ascending' ? 1 : -1;
        }
        return 0;
      });
    }
    return sortableItems;
  }, [items, sortConfig]);

  const requestSort = (key) => {
    let direction = 'ascending';
    if (
      sortConfig &&
      sortConfig.key === key &&
      sortConfig.direction === 'ascending'
    ) {
      direction = 'descending';
    }
    setSortConfig({ key, direction });
  };

  return { items: sortedItems, requestSort, sortConfig };
};

const ProductTable = (props) => {
  const { items, requestSort, sortConfig } = useSortableData(props.products);
  const getClassNamesFor = (name) => {
    if (!sortConfig) {
      return;
    }
    return sortConfig.key === name ? sortConfig.direction : undefined;
  };
  return (
    <table>
      <caption>Products</caption>
      <thead>
        <tr>
          <th>
            <button
              type="button"
              onClick={() => requestSort('name')}
              className={getClassNamesFor('name')}
            >
              Name
            </button>
          </th>
//...
        </tr>
      </thead>
    </table>
  );
};
72%

The next feature we want to see is a way to switch between ascending and descending order. We’ll switch between ascending and descending order by clicking the table heading one more time.,Now, if the direction is ‘ascending’, we’ll do as we did previously. If it’s not, we’ll do the opposite, giving us descending ordering.,Wrapping our code in this function will have huge performance implications for our table sorting!,Here, we accept an array of products and loop them out into our table. It’s static and not sortable at the moment, but that’s fine for now.

First, let’s create a sample table component. It’ll accept an array of products, and output a very basic table, listing out a row per product.

function ProductTable(props) {
  const { products } = props;
  return (
    <table>
      <caption>Our products</caption>
      <thead>
        <tr>
          <th>Name</th>
          <th>Price</th>
          <th>In Stock</th>
        </tr>
      </thead>
      <tbody>
        {products.map(product => (
          <tr key={product.id}>
            <td>{product.name}</td>
            <td>{product.price}</td>
            <td>{product.stock}</td>
          </tr>
        ))}
      </tbody>
    </table>
  );
}

Sorting data in JavaScript is pretty straightforward, thanks to the built-in array function sort(). It’ll sort arrays of numbers and strings without an extra argument:

const array = ['mozzarella', 'gouda', 'cheddar'];
array.sort();
console.log(array); // ['cheddar', 'gouda', 'mozzarella']

Let’s start by sorting the data we get alphabetically by name.

function ProductTable(props) {
  const { products } = props;
  let sortedProducts = [...products];
  sortedProducts.sort((a, b) => {
    if (a.name < b.name) {
      return -1;
    }
    if (a.name > b.name) {
      return 1;
    }
    return 0;
  });
  return (
    <Table>
      {/* as before */}
    </Table>
  );
}

A hook is a special kind of function that lets us “hook” into some of React’s core functionality, like managing state and triggering side effects. This particular hook lets us maintain a piece of internal state in our component, and change it if we want to. This is what we’ll add:

const [sortedField, setSortedField] = React.useState(null);
const ProductsTable = (props) => {
  const { products } = props;
  const [sortedField, setSortedField] = React.useState(null);
  return (
    <table>
      <thead>
        <tr>
          <th>
            <button type="button" onClick={() => setSortedField('name')}>
              Name
            </button>
          </th>
          <th>
            <button type="button" onClick={() => setSortedField('price')}>
              Price
            </button>
          </th>
          <th>
            <button type="button" onClick={() => setSortedField('stock')}>
              In Stock
            </button>
          </th>
        </tr>
      </thead>
      {/* As before */}
    </table>
  );
};

We’re not doing any actual sorting yet though, so let’s fix that. Remember the sorting algorithm from before? Here it is, just slightly altered to work with any of our field names.

const ProductsTable = (props) => {
  const { products } = props;
  const [sortedField, setSortedField] = React.useState(null);
  let sortedProducts = [...products];
  if (sortedField !== null) {
    sortedProducts.sort((a, b) => {
      if (a[sortedField] < b[sortedField]) {
        return -1;
      }
      if (a[sortedField] > b[sortedField]) {
        return 1;
      }
      return 0;
    });
  }
  return (
    <table>

Here’s the new sorting function:

 sortedProducts.sort((a, b) => {
    if (a[sortConfig.key] < b[sortConfig.key]) {
       return sortConfig.direction === 'ascending' ? -1 : 1;
    }
    if (a[sortConfig.key] > b[sortConfig.key]) {
       return sortConfig.direction === 'ascending' ? 1 : -1;
    }
    return 0;
 });
const requestSort = key => {
   let direction = 'ascending';
   if (sortConfig.key === key && sortConfig.direction === 'ascending') {
      direction = 'descending';
   }
   setSortConfig({
      key,
      direction
   });
}
return (
  <table>
    <thead>
      <tr>
        <th>
          <button type="button" onClick={() => requestSort('name')}>
            Name
          </button>
        </th>
        <th>
          <button type="button" onClick={() => requestSort('price')}>
            Price
          </button>
        </th>
        <th>
          <button type="button" onClick={() => requestSort('stock')}>
            In Stock
          </button>
        </th>
      </tr>
    </thead>
  {/* as before */}
  </table>
);
const ProductsTable = (props) => {
      const {
         products
      } = props;
      const [sortConfig, setSortConfig] = React.useState(null);

      React.useMemo(() => {
         let sortedProducts = [...products];
         if (sortedField !== null) {
            sortedProducts.sort((a, b) => {
               if (a[sortConfig.key] < b[sortConfig.key]) {
                  return sortConfig.direction === 'ascending' ? -1 : 1;
               }
               if (a[sortConfig.key] > b[sortConfig.key]) {
                  return sortConfig.direction === 'ascending' ? 1 : -1;
               }
               return 0;
            });
         }
         return sortedProducts;
      }, [products, sortConfig]);
const useSortableData = (items, config = null) => {
   const [sortConfig, setSortConfig] = React.useState(config);

   const sortedItems = React.useMemo(() => {
      let sortableItems = [...items];
      if (sortConfig !== null) {
         sortableItems.sort((a, b) => {
            if (a[sortConfig.key] < b[sortConfig.key]) {
               return sortConfig.direction === 'ascending' ? -1 : 1;
            }
            if (a[sortConfig.key] > b[sortConfig.key]) {
               return sortConfig.direction === 'ascending' ? 1 : -1;
            }
            return 0;
         });
      }
      return sortableItems;
   }, [items, sortConfig]);

   const requestSort = key => {
      let direction = 'ascending';
      if (sortConfig && sortConfig.key === key && sortConfig.direction === 'ascending') {
         direction = 'descending';
      }
      setSortConfig({
         key,
         direction
      });
   }

   return {
      items: sortedItems,
      requestSort
   };
}

Our table code now looks like this:

const ProductsTable = (props) => {
  const { products } = props;
  const { items, requestSort } = useSortableData(products);
  return (
    <table>{/* ... */}</table>
  );
};
const ProductTable = (props) => {
  const { items, requestSort, sortConfig } = useSortableData(props.products);
  const getClassNamesFor = (name) => {
    if (!sortConfig) {
      return;
    }
    return sortConfig.key === name ? sortConfig.direction : undefined;
  };
  return (
    <table>
      <caption>Products</caption>
      <thead>
        <tr>
          <th>
            <button
              type="button"
              onClick={() => requestSort('name')}
              className={getClassNamesFor('name')}
            >
              Name
            </button>
          </th>
         {/* … */}
        </tr>
      </thead>
      {/* … */}
    </table>
  );
};
load more v
65%

If set to true, the first sort direction for this column will be descending instead of ascending,sortDescFirst: BoolOptionalDefaults to falseIf set to true, the first sort direction for this column will be descending instead of ascending,useSortBy is the hook that implements row sorting. It also supports multi-sort (keyboard required).,If set to true, the sorting for this column will be disabled

load more v