2

I'm following a guide I found on StackOverflow to sort an array in order to change the column order desc/asc of a table I'm populating with an API.

I'm using this Stack answer: sort an array with react hooks

Here is the code:

import { useEffect, useState } from 'react';
import './App.css';
import { IoCaretDown } from "react-icons/io5";
import { IoCaretUp } from "react-icons/io5";

function Countries() {
  const sortByName = () => {
    const sorted = [...data].sort((a, b) => {
      console.log('presort', a.name.common, b.name.common)
      return b.name.common - a.name.common;
    });
    console.log('sorted', sorted);
    setData(sorted);
    console.log('data sorted', data);
  };


  const [data, setData] = useState([]);
  useEffect(() => {
    fetch('https://restcountries.com/v3.1/all?fields=name,continents,population,flag')
      .then((resp) => resp.json())
      .then((apiData) => {
        setData(apiData);
      }, []);
  });
  return (
    <div className="app-container">
      <table>
        <thead>
          <tr>
            <th onClick={sortByName}>Name
              <IoCaretDown/>
              <IoCaretUp/>
              
            </th>
            <th>Continent</th>
            <th>Population</th>
            <th>Flag</th>
          </tr>
        </thead>
        <tbody>
          {data.map((country) => (
            <tr  key={country.flag}>
              <td>{country.name.common}</td>
              <td>{country.continents}</td>
              <td>{country.population}</td>
              <td>{country.flag}</td>
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
}

export default Countries;

I'm using the exact same sort as mentioned in the original Stack answer:

const sortByName = () => { const sorted = [...data].sort((a, b) => { console.log('presort', a.name.common, b.name.common) return b.name.common - a.name.common; }); console.log('sorted', sorted); setData(sorted); console.log('data sorted', data); };

But the console.logs show the array unchanged:

enter image description here

I added a console log in the hook to see if the name references are accurate and they're appearing in the log: enter image description here It's not changing the order at all in the array.

Any help would be greatly appreciated.

1 Answer 1

1

The first problem is in your sorting method, here is how you sort a table of strings

const sortByName = () => {
 const sorted = [...data].sort((a, b) => {
   if (b.name.common > a.name.common) {
     return -1;
   }
   if (b.name.common > a.name.common) {
     return 1;
   }
   return 0;
  });
 setData(sorted);
};

The second problem is your useEffect, it does execute after each render and set again the data to the default value (not sorted), you have to add an empty array as dependency to make it execute the first time only

 useEffect(() => {
  fetch(
     'https://restcountries.com/v3.1/all? 
     fields=name,continents,population,flag'
   ).then((resp) => resp.json())
    .then((apiData) => {
      setData(apiData);
   }, []);
 }, []);

Here is a working example https://stackblitz.com/edit/react-rmgzfz?file=src%2FApp.js

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.