I'm working on an React app that lists my favorite music albums. Everything worked fine until i implemented the change order (ascend, descend) and the sort list buttons.
On the first click it doesn't react, but on the second click it logs the value of the previous click and renders the previous value.
I'm fetching the data from server database, and everything works when I manually change order and sort values and than save the changes. It renders immediately and it looks good, but when i implemented the function to change those values on a button click, then the problems started.
I've tried multiple solutions that I found on other similar questions, but nothing worked. I've tried useCallback, I've added useEffect for console.log, I've tried using ordinary variables instead of setState, changing the dependencies in useEffect, and several other solutions I found but nothing worked for me. It always changes on the second click, and then on every other click it shows the previous value.
This is my code:
import { useEffect, useState } from "react";
import Album from "../Album";
export default function IndexPage() {
const [albums, setAlbums] = useState([]);
const [order, setOrder] = useState(1);
const [key, setKey] = useState("title");
const [sort, setSort] = useState({ title: 1 });
useEffect(() => {
fetch(`http://localhost:4000/list?${new URLSearchParams(sort).toString()}`).then(response => {
response.json().then(albums => {
setAlbums(albums);
});
});
}, [albums]);
function toggleOrder() {
order === 1 ? setOrder(-1) : setOrder(1);
setSort({ [key]: order });
console.log(order);
}
function selectSort(selection) {
setKey(selection);
setSort({ [key]: order });
}
return (
<div className="list">
<div className="album-buttons">
<button className="addTrack edit" onClick={toggleOrder}>⬍ Order</button>
<p>|</p>
<div className="sort">
<button className="addTrack edit">Sort by: {key.charAt(0).toUpperCase()+key.slice(1)} ▾</button>
<div className="dropdown-sort">
<button className="addTrack edit" onClick={() => {selectSort("title")}}>Title</button>
<button className="addTrack edit" onClick={() => {selectSort("artist")}}>Artist</button>
<button className="addTrack edit" onClick={() => {selectSort("year")}}>Year</button>
<button className="addTrack edit" onClick={() => {selectSort("genre")}}>Genre</button>
</div>
</div>
</div>
{albums.length > 0 && albums.map((album, i) => (
<Album key={i} {...album} />
))}
</div>
)
}
I understood that React should re-render every time I use setState, but I don't understand why I's not changing in my situation. Any help is very appreciated.