KristoT
KristoT

Reputation: 3

Sorting products by name ASC/DESC, price ASC/DESC in react

So my problem is how i can order my products in the way when i click on option(price) button in productList.js then my products are listed ASC/DESC in price. I have tried many ways but im stuck with this and i can't think any solutions anymore, i hope someone can help me to crack this puzzle with me .

I'm new in react so i hope u understand that it's importat to me.

Context.js

 import React, { Component } from "react";
    import { detailProduct, storeProducts } from "./data";
    
    const ProductContext = React.createContext();
    
    class ProductProvider extends Component {
      state = {
        products: [],
        detailProduct: detailProduct,
        cart: [],
        modalOpen: false,
        modalProduct: detailProduct,
        cartTotal: 0,
        sortOrder: true,
      };


    

  componentDidMount = () => {
    this.setProducts();

    const cart = localStorage.getItem("myCart");
    this.setState(
      { cart: JSON.parse(cart) ? JSON.parse(cart) : [] },
      this.addTotals
    );
  };

  setProducts = () => {
    let tempProducts = [];
    storeProducts.forEach((item) => {
      const singleItem = { ...item };
      tempProducts = [...tempProducts, singleItem];
    });
    this.setState(() => {
      return { products: tempProducts };
    });
  };

  getItem = (id) => {
    const product = this.state.products.find((item) => item.id === id);
    return product;
  };

  handleDetail = (id) => {
    const product = this.getItem(id);
    console.log(id);
    this.setState(() => {
      return { detailProduct: product };
    });
  };

productList.js

 import React, { Component } from "react";
    import Product from "./product";
    import { ProductConsumer } from "../../context";
    import "./productList.scss";
    
export default class productList extends Component {
  render() {
    return (
      <React.Fragment>
        <div className="product">
          <div className="productbox">
            <h1>Products</h1>
              <ProductConsumer>
          {(value) => {
            return (
              <select>
                <option value="Default">Default</option>
                <option value="Price" >
                  Price
                </option>
                <option value="Name" >
                  by name
                </option>
              </select>
            );
          }}
        </ProductConsumer>
           <div className="cardbox"
           <ProductConsumer>
                
                {(value) => {
                  return value.products.map((product) => {
                    return <Product key={product.id} product={product} />;
                  });
                }}
              </ProductConsumer>
            </div>
          </div>
        </div>
      </React.Fragment>
    );
  }
}

Upvotes: 0

Views: 1495

Answers (1)

Ala
Ala

Reputation: 31

you can create sort function and call it when Price option is clicked:

let numbers = [4, 2, 5, 1, 3];
numbers.sort((a, b) => a - b);
console.log(numbers);
// [1, 2, 3, 4, 5]

In your case it should be like this:

// Add a variable to the state to know if the sort is ASC or DESC
  state = {
    products: [],
    detailProduct: detailProduct,
    cart: [],
    modalOpen: false,
    modalProduct: detailProduct,
    cartTotal: 0,
    sortOrder:true, // true for ASC for example

  };
  sortItems = () => {
    if(this.state.sortOrder === true)
        this.state.products.sort((a, b) => a.price - b.price);
    else
        this.state.products.sort((a, b) => b.price - a.price);
    
    //update sortOrder
    this.state.sortOrder === !this.state.sortOrder;

  };

added this by name :


    sortName = () => {
        if (this.state.sortOrder === true)
          this.state.products.sort((a, b) => a.name - b.name);
        else this.state.products.sort((a, b) => b.name - a.name);
    
        //update sortOrder
        // this.state.sortOrder === !this.state.sortOrder;
      };

// you need to call the function when click on the option:

<option value="Price" onClick={this.sortItems}>Price</option>
// and called the function like this:

context.js

<ProductContext.Provider
        value={{
          ...this.state,
          handleDetail: this.handleDetail,
          addToCart: this.addToCart,
          increment: this.increment,
          decrement: this.decrement,
          removeItem: this.removeItem,
          clearCart: this.clearCart,
          sortPrice: this.sortPrice,
          sortName: this.sortName,
        }}
      >
        {this.props.children}
      </ProductContext.Provider>

productList.js

export default class productList extends Component {
  render() {
    return (
      <React.Fragment>
        <div className="product">
          <div className="productbox">
            <h1>Products</h1>
            <ProductConsumer>
              {(value) => {
                return (
                  <select>
                    <option value="Default">Default</option>
                    <option value="Price" onClick={value.sortPrice()}>
                      Price
                    </option>
                    <option value="Name" onClick={value.sortName()}>
                      by name
                    </option>
                  </select>
                );
              }}
            </ProductConsumer>
            <div className="cardbox">
              <ProductConsumer>
                {(value) => {
                  return value.products.map((product) => {
                    return <Product key={product.id} product={product} />;
                  });
                }}
              </ProductConsumer>
            </div>
          </div>
        </div>
      </React.Fragment>
    );
  }
}

Upvotes: 0

Related Questions