x1c 0d1x我想在我的购物车网站过滤属性。我在这里使用redux工具包在我的ReactJS项目。我显示的产品。我在这里使用(https://dummyjson.com/products)API在我的项目中列出我的产品。我想应用类别和价格的过滤器属性。我试过了,但过滤功能不适用。请帮助我如何在redux中应用和制作过滤器属性-下面是代码的所有文件。
productSlice.js
import { createSlice, createAsyncThunk } from "@reduxjs/toolkit";
import axios from "axios";
const baseURL = "https://dummyjson.com/products";
export const STATUSES = Object.freeze({
IDLE: "idle",
ERROR: "error",
LOADING: "loading",
});
export const fetchProducts = createAsyncThunk(
"products/fetch",
async () => {
const res = await axios.get(baseURL);
const data = await res.data;
return data;
}
);
export const getProduct = createAsyncThunk(
"product/getProduct",
async (id, { rejectWithValue }) => {
try {
const response = await axios.get(`${baseURL}/${id}`);
return response.data;
} catch (error) {
return rejectWithValue(error.response);
}
}
);
const productSlice = createSlice({
name: "product",
initialState: {
products: [],
product: {},
status: STATUSES.IDLE,
},
reducers: {
},
extraReducers: (builder) => {
builder
.addCase(fetchProducts.pending, (state, action) => {
state.status = STATUSES.LOADING;
})
.addCase(fetchProducts.fulfilled, (state, action) => {
state.products = action.payload;
state.status = STATUSES.IDLE;
})
.addCase(fetchProducts.rejected, (state, action) => {
state.status = STATUSES.ERROR;
})
.addCase(getProduct.pending, (state, action) => {
state.status = STATUSES.LOADING;
})
.addCase(getProduct.fulfilled, (state, action) => {
state.status = STATUSES.IDLE;
state.product = action.payload;
});
},
});
export const { handlePriceFilter } = productSlice.actions;
export default productSlice.reducer;
Home.js
import { useEffect, useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import { Products, SearchBar } from "../components";
import Filters from "../components/Filters";
import { fetchProducts, STATUSES } from "../redux/features/productSlice";
import { FaFilter } from "react-icons/fa";
import SidebarFilterPanel from "../components/SidebarFilterPanel";
const categories = [
"Smartphones",
"Laptops",
"Fragrances",
"Skincare",
"Groceries",
"Home-Decoration",
];
const Home = () => {
const dispatch = useDispatch();
const { products, status } = useSelector((state) => state.product.products);
const [openFilter, setOpenFilter] = useState(false);
const openFilterPanel = () => setOpenFilter(!openFilter);
useEffect(() => {
dispatch(fetchProducts());
}, []);
useEffect(() => {
document.title = "Shoping Website";
}, []);
return (
<div>
<div className="flex gap-4 justify-between px-4">
<div className="hidden md:block">
<Filters categories={categories} />
</div>
<div className="flex flex-col items-center justify-center w-full">
<div className="flex items-center">
<SearchBar />
<div
onClick={openFilterPanel}
className={`bg-black text-white py-[10px] px-3 md:hidden block rounded cursor-pointer ml-2 mt-3 duration-1000 transition-all`}
>
<FaFilter onClick={openFilterPanel} />
</div>
{openFilter && <SidebarFilterPanel categories={categories} />}
</div>
<div className="grid gap-4 lg:grid-cols-4 sm:grid-cols-2 grid-cols-1 place-items-center mr-auto ml-auto w-full mt-4">
{products &&
products?.map((product) => (
<Products key={product.id} product={product} />
))}
</div>
</div>
</div>
</div>
);
};
export default Home;
Filters.js
import React, { useRef } from "react";
import Slider from "@mui/material/Slider";
import { useDispatch } from "react-redux";
const Filters = ({categories}) => {
const dispatch = useDispatch();
return (
<div className=" w-[200px] shadow-lg h-[600px] flex flex-col px-2 py-10">
<div className="w-[150px] ml-auto mr-auto flex flex-col gap-2">
<p className="font-bold">Price</p>
<Slider
valueLabelDisplay="auto"
aria-labelledby="range-slider"
min={0}
max={1500}
/>
</div>
<div className="px-2 mt-6">
<p className="font-bold mb-2">Catogries</p>
{categories.map((category, index) => (
<p
className="cursor-pointer text-sm my-2 hover:text-orange-500"
key={index}
// onClick={() => handleSelectCategory(category)}
>
{category}
</p>
))}
</div>
<div className="w-[150px] ml-auto mr-auto flex flex-col gap-2 my-8">
<p className="font-bold">Discount</p>
<Slider
valueLabelDisplay="auto"
aria-labelledby="range-slider"
min={0}
max={30}
/>
</div>
<div className="w-[150px] ml-auto mr-auto flex flex-col gap-2 mt-8">
<p className="font-bold">Rating</p>
<Slider
valueLabelDisplay="auto"
aria-labelledby="range-slider"
min={0}
max={5}
/>
</div>
</div>
);
};
export default Filters;
1条答案
按热度按时间e0uiprwp1#
您可以通过创建另一个状态切片来保存筛选器类别及其值来实现这一点。使用产品数组和筛选器值,并在呈现时内联筛选产品。
1.创建过滤器切片并添加到存储区
filter.slice.js
store.js
1.更新
Filter
组件以使用筛选器值并将更新调度到存储区。1.在
Home
组件中呈现时,内联筛选products
数组。