I am building a simple blog app in react and I am trying to sort the new array before setting into existing state array and when I try to sort it then It is showing unexpected results and it is not sorting the array the way I am expecting to.
App.js
function Blog() {
const [blogs, setBlogs] = useState([]);
const fetchBlogs = () => {
axios.get("/api/blogs/").then((res) => {
const sortArray = res.data.blogs
sortArray.sort((a, b) => (a.id > b.id) ? 1 : -1)
setBlogs((prev) => {
return prev.concat(sortArray);
});
})
}
return (
<>
{blogs?.map((res) =>
{res.id}
)}
</>
)
}
I am returning last 5 blogs from the database and then after it and then after it.
So First blogs are like :-
[
{
"id": 190,
"title": "Last blog"
},
{
"id": 189,
"title": "Last blog"
},
{
"id": 188,
"title": "Last blog"
},
{
"id": 187,
"title": "Last blog"
},
{
"id": 188,
"title": "Last blog"
},
]
And I am sorting it to show biggest first like 190, 189, 188,...
It is sorting for the first 5 blogs without any problem, but I load more blogs on click then It is sorting like 187, 186, 185, 184, 183, 190, 189, 188...
which is unexpected.
I tried using concat
method using
response.sort((a, b) => (a.id > b.id) ? 1 : -1)
setBlogs((prev) => {
return prev.concat(sortArray);
});
What I am trying to do? I am trying to sort the array according to the id with current state and newly fetched state and set into state.
Any help would be much Appreciated. Thank You
CodePudding user response:
Assuming that your are calling fetchBlogs after every scroll, i.e at a time 5 blogs, you are making sure your prev is sorted and your sortArray is sorted. But you are not ensuring that your combination of prev and sortedArray is sorted. Which means you would be concatenating two sorted arrays of size 5 each but the entire 10 elements need not be in sorted order.
i.e fetch first instance arrays of ids 10, 7, 11, 4, 6 it gets sorted to 11,10,7,6,4 Second instance fetch retrieves 45, 3, 56, 2 , 1 it gets sorted to 56, 45, 3, 2, 1
now you can concatenating the two will not work.
Rather than sorting and concatenating, it might make sense to concatenate and then sort the entire entry. Now this might have implications to time/cost as the size grows.
const fetchBlogs = () => {
axios.get("/api/blogs/").then((res) => {
const sortArray = res.data.blogs
setBlogs((prev) => {
var newArray = prev.concat(sortArray);
return newArray.sort((a, b) => (a.id > b.id) ? 1 : -1)
});
})
}