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}.
<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;
EDIT:
if you have a better implementation of this please let me know.
CodePudding user response:
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);
};