React中如何传递筛选数组至其他组件且不影响原数组
问题分析与解决方案
你的核心问题是把原始数据和筛选后的数据共用了同一个state,导致每次搜索后原始数据被覆盖,后续筛选都是基于已过滤的结果,自然会出现“重置”的问题;另外清空搜索时也没有正确恢复原始数据。
修复步骤:
分离原始数据与筛选状态
- 用单独的state存储从API获取的原始数据,不要直接修改它
- 用另一个state存储搜索关键词,而不是直接修改数据数组
使用
useMemo计算筛选结果- 基于原始数据和搜索关键词,通过
useMemo实时计算筛选后的数组,避免不必要的重渲染
- 基于原始数据和搜索关键词,通过
修改后的代码示例:
import React, { useState, useEffect, useMemo } from "react"; import { Search } from "carbon-components-react"; import { debounce } from 'lodash'; const ComponentA = () => { // 原始数据(实际项目中从API获取) const originalArr = [ { name: "GARCIA, LALITA M", fname: "LALITA", lname: "GARCIA", mname: "M", id: "lxgFfg", userType: "FRN", userStatus: "A", type: "User", brands: ["PHI"] }, { name: "ANDREW, DONALD M", fname: "DONALD", lname: "ANDREW", mname: "M", id: "lxgHJg", userType: "FRN", userStatus: "A", type: "User", brands: ["PHI"] } ]; // 存储原始数据的state(实际项目中用useEffect从API获取并赋值) const [originalList, setOriginalList] = useState(originalArr); // 存储搜索关键词的state const [searchKeyword, setSearchKeyword] = useState(""); // 使用useMemo计算筛选后的数组,只有当原始数据或搜索关键词变化时才重新计算 const filteredList = useMemo(() => { if (!searchKeyword.trim()) { // 无搜索内容时返回原始数组 return originalList; } const lowerKeyword = searchKeyword.toLowerCase(); return originalList.filter(ele => { const lowerName = ele.name.toLowerCase(); const lowerId = ele.id.toLowerCase(); return lowerName.includes(lowerKeyword) || lowerId.includes(lowerKeyword); }); }, [originalList, searchKeyword]); // 防抖处理搜索输入 const debouncedSearch = useMemo(() => debounce((value) => setSearchKeyword(value), 500), []); // 实际项目中从API获取原始数据的逻辑 useEffect(() => { // 模拟API请求 const fetchData = async () => { // const response = await fetch('your-api-url'); // const data = await response.json(); // setOriginalList(data); }; fetchData(); }, []); return( <> <Search light closeButtonLabelText="Search" id="search-1" labelText="Search User" onChange={(event) => debouncedSearch(event.target.value)} size="lg" /> <ComponentB unassignedStoresList={filteredList} /> </> ); }
关键改进点:
- 数据分离:
originalList保存原始数据,永远不被修改;searchKeyword仅存储搜索输入,两者职责清晰 - 高效计算:
useMemo确保只有当依赖项(原始数据或搜索词)变化时才重新计算筛选结果,提升性能 - 逻辑清晰:清空搜索时自动返回原始数组,无需额外处理
- 防抖优化:用
useMemo包裹防抖函数,避免组件重渲染时重复创建防抖函数
内容的提问来源于stack exchange,提问作者Maulik
相关产品推荐
相关产品推荐

