1

Something's wrong with my code and I have no clue what it is. I hope someone can help me with this :((

I have this provider:

export const ProductProvider = ({ children }) => {

    const [priceFilter, setPriceFilter] = useState('no'); //'asc','desc','no'
    
    const [products, setProducts] = useState([])
    
    const [activeCategory, setActiveCategory] = useState(['category 1', 'category 2', 'category 3']);

    const productsData = {
        products,
        setProducts,
        priceFilter,
        setPriceFilter,
        activeCategory,
        setActiveCategory,
        categories
    }

    return (
        <ProductContext.Provider value={productsData}>
            { children }
        </ProductContext.Provider>
    )
}

I have this custom hook, it just has one function by now:

export const useProductList = () => {

    const {
      priceFilter, 
      activeCategory,
    } = useContext( ProductContext );

    const productsJson = productsjson.products;

    const getProductsToShow = () => {

      let productsToShow = productsJson;
      
      // This will get all the products that belongs to the activeCategory
      if ( activeCategory !== 'all' ) {
        productsToShow = productsToShow.filter(product => {
            return product.category === activeCategory
        })
      }
      
      // This will sort the products by price
      if (priceFilter === 'asc') {
        productsToShow = productsToShow.sort(({price:a}, {price:b}) => b-a);
      } 

      if (priceFilter === 'desc') {
        productsToShow = productsToShow.sort(({price:a}, {price:b}) => a-b);
      };

      return productsToShow;

    }

    return {
      getProductsToShow
    }
}

Aaaaaaand I have this component:

export const ProductList = () => {

  const { getProductsToShow } = useProductList();
  const { products, activeCategory, priceFilter, setProducts } = useContext( ProductContext );
  
  // When I update activeCategory or priceFilter it will update the products state
  useEffect(() => {
    const productsToShow = getProductsToShow();
    setProducts(productsToShow);
    
  }, [ activeCategory, priceFilter ])
  
  return (
    <>
      <FilterBar />
      <div className='container mt-5 product-list'>
        {
          products.map( product => {
            return <Product key={product.id} {...product} />
          })
        }
      </div>
    </>
  )
}

This is the function that changes the price filter and it works perfectly, the problem is not here but I leave it just in case:

  const clickPriceFilter = () => {
    switch (priceFilter) {
      case 'no':
        setPriceFilter('asc');
        break;
      case 'asc':
        setPriceFilter('desc');
        break;
      case 'desc':
        setPriceFilter('no');

        break;
    }
  }

The thing is that I can see the products state changing through react devtools but it won't re-render the first time I change the priceFilter, it will work from the second time I change it. It's like it re-render it before changing the products state

Not sure if it's the best practice but I let you here a GIF so you can see the problem in the UI.

enter image description here

Sunderam Dubey
  • 1
  • 11
  • 20
  • 40
AngelQuesada
  • 387
  • 4
  • 19
  • 1
    Try replacing both `productsToShow.sort(({price:a}, {price:b}) => b-a)` with `[...productsToShow].sort(({price:a}, {price:b}) => b-a)` – Konrad Feb 26 '23 at 18:46

0 Answers0