You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 00:03:18