I am working on a E-Commerce site in React that displays a list of items that are derived from a JSON file. The JSON file includes info such as the price, model, image, etc.
I'm trying to add "Sort by: Price" functionality to the site. The function I have right now works correctly in sorting the JSON data:
import products from "../data/products.json";
function Shop(){
const [items, setItems] = useState();
function sortProducts() {
setItems(products.sort(sortByProperty("price")));
}
function sortProductsReverse(){
setItems(products.sort(sortByProperty("price")).reverse);
}
return (
{products.map((product) => (
<React.Fragment>
<Product {...product} />
</React.Fragment> )
}
}
sortByProperty
does the sorting logic from lowest to highest, sortProducts
sorts from lowest to highest, sortProductsReverse
sorts from highest to lowest. Product
is the component that takes in the JSON data and displays everything.
When the page is first loaded, all the products are displayed correctly without being sorted. When a button is onClicked to sortProducts
or sortProductsReverse
, it works. However, it works only once. The items cannot be sorted/re-rendered again.
I think I'm missing something in items
useState, but I'm not sure what I should do.
CodePudding user response:
For your component to rerender, you need to set the state with a new object reference, React then compares previous and current state, and if they are not equal, it rerenders the component.
In your case, items
is initially undefined
, and when you set it as products
, the component rerenders.
After that, everytime you call products.sort
, it sets items
the same object from before, because sort
method in JavaScript mutates the original object, but doesn't return a new one.
To solve the problem, everytime call setItems
with a new object:
setItems([...products].sort(sortByProperty("price")));