Home > other >  Sorting a JSON file in React, component not rerendering onClick
Sorting a JSON file in React, component not rerendering onClick

Time:07-18

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")));

  • Related