I am currently using a small Shopping Cart project using React and Redux, Node I built the function for filtering products by size and Sort And it was working fine but when I used Redux the filtering process doesn't work anymore I tried it a lot
Store.js
import {createStore,compose,applyMiddleware} from 'redux'
import reducer from './Reducer/Reducer'
import reduxthunk from 'redux-thunk'
const initialState = {}
const enhancer = window.__REDUX_DEVTOOLS_EXTENTION_COMPOSE__ || compose
const store = createStore(reducer,initialState,enhancer(applyMiddleware(reduxthunk)))
export default store
Types.js
export const FETCH_PRODUCTS="FETCH_PRODUCTS"
export const FILTER_SIZE="FILTER_SIZE"
export const FILTER_SORT="FILTER_SORT"
ProductsActions.js
import { FETCH_PRODUCTS,FILTER_SIZE,FILTER_SORT} from './Types'
export const fetchProducts = () => {
return (dispatch) => {
fetch('/api/products').then(res => res.json()).then(data => {
dispatch({
type: FETCH_PRODUCTS,
data: data
})
})
}
}
export const filterdSize = (products,value) => {
return (dispatch) => {
let productClone = [...products]
let newProduct = productClone.filter(p => p.size.indexOf(value) != -1)
dispatch({
type: FILTER_SIZE,
data: {
size: value,
products: value == "ALL" ? products : newProduct
}
})
}
}
export const filterdSort = (products, value) => {
return (dispatch) => {
let productClone = [...products];
let newProduct = productClone.sort(function (a, b) {
if (value == "lowest") {
return a.price - b.price;
} else if (value == "highest") {
return b.price - a.price
} else {
return a.id < b.id ? 1 : -1
}
})
dispatch({
type:FILTER_SORT,
data:{
sort:value,
products:newProduct
}
})
}
}
ProductReducer.js
import {FETCH_PRODUCTS,FILTER_SIZE,FILTER_SORT} from '../Actions/Types'
const ProductReducer=(state={},action)=>{
switch(action.type) {
case FETCH_PRODUCTS:
return {
products:action.data,
filterProducts:action.data
}
case FILTER_SIZE:
return {
...state,
size:action.data.size,
filterProducts:action.data.products
}
case FILTER_SORT:
return {
...state,
sort: action.data.sort,
filterProducts:action.data.products
}
default:
return state
}
}
export default ProductReducer
Reducer.js
import ProductReducer from './ProductReducer'
import {combineReducers} from 'redux'
export default combineReducers({
products:ProductReducer
})
Filter.js
import React from 'react'
import './Filter.css'
import Flip from 'react-reveal/Flip';
import { connect } from 'react-redux'
import { filterdSize, filterdSort } from '../../store/Actions/Products'
const Filter = (props) => {
return (
<Flip left cascade>
{props.filterProducts && <div className="filter-wrapper">
<h2 className="filter-title">Filter</h2>
<div className="nom-of-product">number of product {props.filterProducts.length} </div>
<div className="filter-by-size">
<span className="span-title">Size</span>
<select className="filter-select" onChange={(e) => filterdSize(props.products, e.target.value)} value={props.size}>
<option value="ALL">ALL</option>
<option value="S">S</option>
<option value="M">M</option>
<option value="L">L</option>
<option value="XL">XL</option>
<option value="XXL">XXL</option>
</select>
</div>
<div className="filter-by-size">
<span className="span-title">Order</span>
<select className="filter-select" onChange={(e) => filterdSort(props.filterProducts, e.target.value)} value={props.sort}>
<option value="lastes">Lastes</option>
<option value="lowest">Lowest</option>
<option value="highest">Highest</option>
</select>
</div>
</div>}
</Flip>
)
}
export default connect((state) => {
return {
sort: state.products.sort,
size: state.products.size,
products: state.products.products,
filterProducts: state.products.filterProducts
}
}, { filterdSize, filterdSort })(Filter)
CodePudding user response:
You should dispatch your actions, not just call them so you would want to get dispatch function using useDispatch from react-redux
const dispatch = useDispatch();
And then call your actions with dispatch For example:
onChange={(e) => dispatch(filterdSize(props.products, e.target.value))}