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>
CodePudding user response:
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.
CodePudding user response:
setSort function will not set the value instantly. it only changes the value on it next render
best method is to use useEffect hook
const [carList, setCarList] = useState(cars)
const [sorting, setSorting] = useState("pricelow")
useEffect(()=> {
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)
}
},[sorting])
<select className="form-select w-25" onChange={(e)=>setSorting(e.target.value)} 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>