'React map() function only firing once

I have an e-commerce website and a filter which filters products based on brand.

My Reducer:

const INITIAL_STATE = {
  products: [
    {
      id: 1,
      type: "joggers",
      category: "pant",
      gender: "female", 
      color: "Green",
      brand: "Wrangler",
      name: "Camo Print Joggers Pants",
    },
    {
      id: 2,
      type: "joggers",
      category: "pant",
      gender: "male",
      color: "Green",
      brand: "US Polo Assn",
      name: "Camoflage Print Slim Fit Jogger Pants",
    },  
  ],
  brands: ["Wrangler", "Vermo Moda", "AJIO", "HRX", "Nike", "Puma", "US Polo Assn", "Levis", "The Roadster", "H & M", "Jack & Jones"],
  
  refinedProducts: [],
};


const shopReducer = (state = INITIAL_STATE, action) => {
  switch (action.type) {
    
 case actionTypes.REFINE_BY_BRAND:
  
  if (action.payload.boolVal === true) {
    INITIAL_STATE.products.forEach((element) => {
      if(element.brand === action.payload.brand){
        state.refinedProducts.push(element);
      }
    });
      return {
        ...state,
        products: state.refinedProducts,
      };
  }
  else{
    INITIAL_STATE.products.forEach((element) => {
      if(element.brand === action.payload.brand){
        state.refinedProducts.pop(element);
      }
    });
    return {
      ...state,
      products: state.refinedProducts,
    };
  }

    
    default:
      return state;
  }
};

export default shopReducer;

My REACT component Code:

import React from 'react';
import "./crownFashionStore.css"
import { connect } from "react-redux";
import { refineByFemale, refineByMale, refineByBrand, refineByColor } from "../../redux/shop/shop-actions";
import Product from '../product/Product';


function CrownFashionStore(props) {
    console.log(props);
  return (
    <div className="shop-container">       
          <div className="brands">
            <p>Brands</p>
            {props.brands.map((brand, index) => {
              return (
                <div key={index} className="filter">
                  <input
                    value={brand}
                    onClick={(e) => {
                      const brand = e.target.value;
                      const boolVal = e.target.checked;
                      props.refineByBrand(brand, boolVal);
                      console.log(props);
                    }}
                    type="checkbox"
                  />
                  <label htmlFor="">{brand}</label>
                </div>
              );
            })}
          </div>

        <div className="body-right">
          {props.products.map((product) => {
            return <Product key={product.id} data={product} />; //<-- triggers only once
          })}
        </div>
    </div>
  );
};

const mapStateToProps = (state) => {
  return {
    products: state.shop.products,
    brands: state.shop.brands,
    refinedProducts: state.shop.refinedProducts,
  };
};

const mapDispatchToProps = (dispatch) => {
  return {
    refineByBrand: (brand, boolVal) => dispatch(refineByBrand(brand, boolVal)),
  };
};

export default connect(mapStateToProps, mapDispatchToProps)(CrownFashionStore);

Whenever I click on on the Input checkbox used to filter products brand wise, the map function gets triggered and renders desired Products on the screen. But when I click on some other brand, the state(products) changes happen accordingly but the problem is that the Map function doesn't get triggered the second time hence unable to output desired result. Can someone help me identify the mistake I've made here



Solution 1:[1]

Change products to refinedProducts in component and also change your reducer to the code below

case actionTypes.REFINE_BY_BRAND:

if (action.payload.boolVal === true) {
  const filteredProduct = Array.from(state.products);
  return {
    ...state,
    refinedProducts: filteredProduct.filter(a=>a.brand === action.payload.brand),
  };
}
else{
 const filteredProduct = Array.from(state.refinedProducts);

   return {
    ...state,
    refinedProducts: filteredProduct.filter(a=>a.brand !== action.payload.brand),
   };
 }

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 hassanqshi