I'm trying to create product filter function for my store project.
Now it looks like this
useEffect(() => {
let newClothesData = [...clothesData]
let newFilteredData
const filterArray = () => {
newFilteredData = newClothesData
.filter(({ title }) => title.toLowerCase().includes(filterValue))
.map(({ title, id, price, image, description }) => ({ title, id, price, image, description }))
setFilteredData(newFilteredData)
}
filterArray()
}, [clothesData, filterValue])
filterValue is an empty array which is being updated by pressing checkboxes, then it becomes array of strings, (f.e. ['backpack', 'jacket']. What I want to do is to filter newClothesData, which is an array of objects, and check if object's key title matches any of these strings stored in filterValue's array.
F.e. If user presses backpacks and jackets checkboxes, function will fill newFilteredData with objects that have backpack or jacket indluced in their title key value.
I don't really know how to achieve this. At this moment filter works only for 1 or 0 string being stored in filterValue array
EDIT:
import React, { useState, useEffect } from 'react'
import ProductItem from './ProductItem/ProductItem'
import { useSelector } from 'react-redux'
import './ProductList.css'
const ProductList = () => {
const clothesData = useSelector(state => state.fetchClothes.clothes)
const sortType = useSelector(state => state.sortingClothes.sortAs)
const filterValue = useSelector(state => state.filteringClothes.filterValue)
const [filteredData, setFilteredData] = useState([])
const [sortedData, setSortedData] = useState([])
useEffect(() => {
let newClothesData = [...clothesData]
const filter = new Set(filterValue)
if (filterValue.length === 0) {
setFilteredData(newClothesData)
} else {
let newFilteredData = newClothesData
.filter(({ title }) => filterValue.includes(title.toLowerCase()))
.map(({ title, id, price, image, description }) => ({ title, id, price, image, description }))
setFilteredData(newFilteredData)
console.log(newFilteredData)
}
}, [clothesData, filterValue])
useEffect(() => {
let newClothesData = [...filteredData]
const sortArray = type => {
const types = {
none: 'none',
priceAsc: 'price',
priceDes: 'price',
titleAsc: 'title',
titleDes: 'title',
}
const sortProperty = types[type]
if (sortType === 'priceAsc') {
return newClothesData.sort((a, b) => (a[sortProperty] > b[sortProperty] ? 1 : -1))
} else if (sortType === 'priceDes') {
return newClothesData.sort((a, b) => (a[sortProperty] < b[sortProperty] ? 1 : -1))
} else if (sortType === 'titleAsc') {
return newClothesData.sort((a, b) => (a[sortProperty].toUpperCase() > b[sortProperty].toUpperCase() ? 1 : -1))
} else if (sortType === 'titleDes') {
return newClothesData.sort((a, b) => (a[sortProperty].toUpperCase() < b[sortProperty].toUpperCase() ? 1 : -1))
} else {
return newClothesData
}
}
setSortedData(newClothesData)
sortArray(sortType)
}, [sortType, filteredData])
return (
<div className='product-list'>
{sortedData.map(item => {
return <ProductItem key={item.id} clothesData={item} />
})}
</div>
)
}
export default ProductList
This is my entire component. It fetches to the redux store data from fakestore api and it gets items from clothes category only. I get this clothes data with useSelector in ProductList component aswell as the current filterValue. clothesData has 10 objects in an array.