I’m trying to sort some data in my application. I’d like to support the following options:
- Price (low to high)
- Price (high to low)
- Mileage (low to high)
- Mileage (high to low)
It looks like price sorting is working. However, when I click on “lowest mileage”, it keeps showing the highest price results – the old value of sorting
. I tried useEffect
, but I couldn’t make it work. Here’s my code:
App.js
const [carList, setCarList] = useState(cars) const [sorting, setSorting] = useState("pricelow") const handleSort = (e) => { setSorting(e.target.value) if (sorting === "pricelow"){ const newlist = carList.sort((a,b) => { return parseInt(b.carPrice) - parseInt(a.carPrice) }) setCarList(newlist) } if (sorting === "pricehigh"){ const newlist = carList.sort((a,b) => { return parseInt(a.carPrice) - parseInt(b.carPrice) }) setCarList(newlist) } if (sorting === "kmlow"){ const newlist = carList.sort((a,b) => { return parseInt(a.carMileage) - parseInt(b.carMileage) }) setCarList(newlist) } }
AdsList.js
<select className="form-select w-25" onChange={handleSort} value={sorting}> <option value="pricelow">Sort By Lowest Price</option> <option value="pricehigh">Sort By Highest Price</option> <option value="kmlow">Sort By Lowest Km</option> <option value="kmhigh">Sort By Highest Km</option> </select>
Advertisement
Answer
This is happening because the setSorting
doesn’t change the sorting
value straight away but rather waits until the component re-renders. See https://reactjs.org/docs/react-component.html#setstate
Do this instead:
const [sorting, setSorting] = useState("pricelow") const handleSort = (e) => { const sortValue = e.target.value; setSorting(sortValue) if (sortValue === "pricelow"){ const newlist = carList.sort((a,b) => { return parseInt(b.carPrice) - parseInt(a.carPrice) }) setCarList(newlist) } if (sortValue === "pricehigh"){ const newlist = carList.sort((a,b) => { return parseInt(a.carPrice) - parseInt(b.carPrice) }) setCarList(newlist) } if (sortValue === "kmlow"){ const newlist = carList.sort((a,b) => { return parseInt(a.carMileage) - parseInt(b.carMileage) }) setCarList(newlist) } }
Another tip, use a switch/case
for cleaner code.