React表格添加搜索功能的正确实现,是否可以不使用两个useState钩子?
React表格搜索功能优化解答
可以不用两个useState实现更简洁的代码
你的需求完全可以只保留1个存储原始数据的state,不用单独把筛选结果存成state。原因是筛选结果属于派生状态:它的值完全可以通过原始数据 + 搜索关键词计算得到,没必要单独存储在state中,反而增加维护成本。
你可以把原来存储筛选结果的filter state替换为存储用户输入的搜索关键词的state,渲染时直接做过滤即可;如果数据量较大,用useMemo缓存筛选结果避免重复计算即可,优化后的参考代码如下:
import React, { useState, useEffect, useMemo } from 'react'; import axios from 'axios'; import Table from '@mui/material/Table'; import TableHead from '@mui/material/TableHead'; import TableBody from '@mui/material/TableBody'; import TableRow from '@mui/material/TableRow'; import TableCell from '@mui/material/TableCell'; import DeleteIcon from '@mui/icons-material/Delete'; import TextField from '@mui/material/TextField'; export default function ShowProject() { const [data, setData] = useState([]); // 替换原来的filter state,仅存储用户输入的搜索关键词 const [searchVal, setSearchVal] = useState('') useEffect(() => { const fetchData = async () => { const result = await axios( 'http://127.0.0.1:5000/pr' ); setData(result.data); // 无需额外同步更新筛选结果 } fetchData() }, []); // 数据量较大时用useMemo缓存,仅当原始数据或搜索关键词变化时才重新计算筛选结果 const filteredData = useMemo(() => { const searchStr = searchVal.toString().toLowerCase().trim(); if (!searchStr) return data; return data.filter(row => row.customer.toString().toLowerCase().includes(searchStr) ) }, [data, searchVal]) return ( <div> <div> <TextField onChange={(e) => setSearchVal(e.target.value)} /> <Table> <TableHead> <TableRow> <TableCell>Project</TableCell> <TableCell>Code</TableCell> <TableCell>Customer</TableCell> <TableCell></TableCell> </TableRow> </TableHead> <TableBody> {filteredData.map(item => ( <TableRow key={item.db_id}> <TableCell>{item.project_name}</TableCell> <TableCell>{item.project_code}</TableCell> <TableCell>{item.customer}</TableCell> <TableCell><DeleteIcon /></TableCell> </TableRow> ))} </TableBody> </Table> </div> </div> ) }
如果你的数据量很小(百条级别),甚至可以省略useMemo,直接在渲染时写过滤逻辑即可,代码会更简洁。
原有代码的潜在副作用
- 状态同步风险:后续如果需要修改原始数据(比如增删改条目),你需要同时更新
data和filter两个state,只要漏更其中一个就会出现页面显示和实际数据不一致的问题,维护成本很高。 - 冗余内存占用:同时存储两份高度相似的数组数据,小数据量下感知不明显,当数据量达到数千、上万条时会产生不必要的内存开销。
- 逻辑维护成本高:筛选规则和state更新逻辑拆分在两处,后续如果要调整搜索规则(比如新增搜索字段、调整匹配逻辑),需要同步修改筛选逻辑和state赋值逻辑,容易出遗漏。
内容的提问来源于stack exchange,提问作者Alecbalec
相关产品推荐
相关产品推荐

