Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

React: Data.map not rerendering after data state has been updated

I am trying to learn how to sort some data using react and TailwindCss, but upon trying I found a problem which I can’t put my finger on, after sorting the data array it’s not data.map is not re-rendering and I don’t know why, can someone help me understand how to fix it, and why this happens.

import { useState, useEffect } from "react";
import axios from "axios";

function App() {
  const [data, setData] = useState([]);

  // this is the sorting function
  const sortData = () => {
    setData(data.sort((a, b) => a.firstName.localeCompare(b.firstName)));
    console.log("sort",data);
  };

  useEffect(() => {
    axios
      .get("https://dummyapi.io/data/v1/user?limit=50", {
        headers: {
          "app-id": "6200ff0858dcad3e84d67c55",
        },
      })
      .then((res) => {
        setData(res.data.data);
      })
      .catch((err) => {
        console.log(err);
      });
  }, []);

  useEffect(() => {
    console.log(data);
  }, [data])

  return (
    <div className="flex justify-center min-h-screen App bg-background min-w-screen">
      <div className="container">
        <div className="flex flex-col items-center gap-4 py-5">
          <h1 className="text-3xl">Filter & sorting app</h1>
          <div className="relative w-full">
            <div className="right-0 ">
              <select className="flex content-end px-3 py-2 bg-white shadow-sm rounded-xl">
                <option
                  value="volvo"
                  className="text-gray-100"
                  selected
                  disabled
                  hidden
                >
                  Sort by
                </option>
                <option value="saab" onClick={sortData}>
                  Ascending
                </option>
                <option value="opel">Descending</option>
              </select>
            </div>
          </div>
          <div className="w-full flex justify-center gap-8 flex-wrap bg-white p-8 min-h-[300px] border-2 rounded-xl">
            {/* here i map on the data state but it does nor re-render after data has changed  */}
            {data?.length > 0 ? (
              data.map((user) => (
                <div
                  className="bg-blue-300 sm:w-[200px] sm:h-[200px] w-[150px] h-[150px] rounded-3xl p-4 flex flex-col items-center mt-8"
                  key={user.id}
                >
                  <img
                    src={user.picture}
                    alt={`"user_"${user.id}`}
                    className="relative w-20 h-20 rounded-full -top-12"
                  />
                  <div className="flex flex-row -mt-6 text-center sm:mt-0">
                    <h1 className="text-xl capitalize sm:text-3xl">
                      {user.title}.&nbsp;
                      <p className="text-sm sm:text-xl">
                        {user.firstName} {user.lastName}
                      </p>
                    </h1>
                  </div>
                </div>
              ))
            ) : (
              <div className="flex items-center justify-center">
                <h1 className="text-3xl">Loading...</h1>
              </div>
            )}
          </div>
        </div>
      </div>
    </div>
  );
}

export default App;

PS: if you have a better implementation of this please let me know.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

This sort function does not return any array. so instead to this:

  const sortData = () => {
    setData(data.sort((a, b) => a.firstName.localeCompare(b.firstName)));
  };

Try this

  const sortData = () => { 
    var newArr = [...data];
    newArr.sort((a, b) => a.firstName.localeCompare(b.firstName))
    setData(newArr);
  };
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading