ReactJS中价格排序筛选后无法恢复初始状态的解决方法
问题原因
核心问题是**Array.sort()是原地排序方法**,会直接修改原始的data数组。当你点击「最低价格」或「最高价格」后,原data已经被改变为排序后的状态,后续点击「全部」时,即使复制data,拿到的也是被修改后的版本,自然无法恢复初始状态。
解决方案
1. 保存初始数据副本
首先在组件顶部创建一份初始数据的副本,确保后续所有操作都基于这份未被修改的原始数据:
import React, { useState } from "react"; import Products from "./Components/Products/Products"; import SearchInput from "./Components/SearchInput/SearchInput"; import data from "./utils/data"; const App = () => { // 保存初始数据的副本,避免原数组被修改 const originalData = [...data]; const [searchValue, setSearchValue] = useState(""); // 初始化状态为原始数据副本 const [productsInfo, setProductsInfo] = useState([...originalData]); // ... 其他代码 };
2. 修改排序逻辑,避免修改原数据
所有排序操作都基于originalData的副本进行,不再直接操作原data:
const selectedChangeFilter = (e) => { const { value } = e.target; if (value === "sporting goods") { const sportingGoods = originalData.filter( (product) => product.category === "Sporting Goods" ); setProductsInfo(sportingGoods); } if (value === "electronics") { const electronicsGoods = originalData.filter( (product) => product.category === "Electronics" ); setProductsInfo(electronicsGoods); } if (value === "lowest price") { // 基于原始数据副本创建新数组后再排序 const lowestPriceGoods = [...originalData].sort((el1, el2) => el1.price.localeCompare(el2.price, undefined, { numeric: true }) ); setProductsInfo(lowestPriceGoods); } if (value === "highest price") { // 同样基于原始数据副本操作 const highestPriceGoods = [...originalData].sort((el1, el2) => el2.price.localeCompare(el1.price, undefined, { numeric: true }) ); setProductsInfo(highestPriceGoods); } if (value === "all") { // 恢复为原始数据副本 setProductsInfo([...originalData]); } };
3. 修正搜索逻辑的数据源
搜索功能同样要基于originalData,避免依赖已被筛选/排序后的productsInfo:
const searchProducts = () => { const trimmedSearchValue = searchValue.toLowerCase().trim(); if (trimmedSearchValue === "") { setProductsInfo([...originalData]); } else { const seekedItem = originalData.filter( (product) => product.name.toLowerCase().trim().includes(trimmedSearchValue) || product.category.toLowerCase().trim().includes(trimmedSearchValue) ); setProductsInfo(seekedItem); } };
4. 调整组件传参
由于searchProducts不再需要传入参数,修改Products组件的传参:
return ( <div> <SearchInput handleChange={handleChange} searchValue={searchValue} selectedChangeFilter={selectedChangeFilter} /> <Products searchValue={searchValue} productsInfo={productsInfo} searchProducts={searchProducts} /> </div> );
完整修改后代码
import React, { useState } from "react"; import Products from "./Components/Products/Products"; import SearchInput from "./Components/SearchInput/SearchInput"; import data from "./utils/data"; const App = () => { const originalData = [...data]; const [searchValue, setSearchValue] = useState(""); const [productsInfo, setProductsInfo] = useState([...originalData]); const handleChange = (e) => { setSearchValue(e.target.value); }; const selectedChangeFilter = (e) => { const { value } = e.target; if (value === "sporting goods") { const sportingGoods = originalData.filter( (product) => product.category === "Sporting Goods" ); setProductsInfo(sportingGoods); } if (value === "electronics") { const electronicsGoods = originalData.filter( (product) => product.category === "Electronics" ); setProductsInfo(electronicsGoods); } if (value === "lowest price") { const lowestPriceGoods = [...originalData].sort((el1, el2) => el1.price.localeCompare(el2.price, undefined, { numeric: true }) ); setProductsInfo(lowestPriceGoods); } if (value === "highest price") { const highestPriceGoods = [...originalData].sort((el1, el2) => el2.price.localeCompare(el1.price, undefined, { numeric: true }) ); setProductsInfo(highestPriceGoods); } if (value === "all") { setProductsInfo([...originalData]); } }; const searchProducts = () => { const trimmedSearchValue = searchValue.toLowerCase().trim(); if (trimmedSearchValue === "") { setProductsInfo([...originalData]); } else { const seekedItem = originalData.filter( (product) => product.name.toLowerCase().trim().includes(trimmedSearchValue) || product.category.toLowerCase().trim().includes(trimmedSearchValue) ); setProductsInfo(seekedItem); } }; return ( <div> <SearchInput handleChange={handleChange} searchValue={searchValue} selectedChangeFilter={selectedChangeFilter} /> <Products searchValue={searchValue} productsInfo={productsInfo} searchProducts={searchProducts} /> </div> ); }; export default App;
内容的提问来源于stack exchange,提问作者user296308
相关产品推荐
相关产品推荐

