Material UI搜索筛选TextField清空与默认状态恢复问题
React + Material UI 搜索筛选组件重置问题
我是ReactJS新手,用Material UI开发时遇到两个问题:
- 给数据表格的搜索筛选组件加了重置按钮,但点击后输入框标签没回到输入框内部(仍停留在边框上方);
- 把搜索值存在state后,搜索总是慢一步(比如输入‘US’时匹配‘USA’,输入‘USA’时匹配‘USAF’),而且调用重置函数清空筛选值没反应。
希望实现:搜索即时生效,点击重置按钮后清空输入框、表格显示未筛选结果,同时输入框标签回到内部。
现有代码
dataTable.js
const [inputValue, setInputValue] = useState('') const [searchFn, setSearchFn,] = useState({ fn: items => { return items; } }); // 搜索数据 const handleSearch = e => { setInputValue(e.target.value) // 输入框显示的值 let query = (e.target.value).toString().toLowerCase(); setSearchFn({ fn: items => { if (query === "") return items; else return items.filter(x => (x.tankName !== null && x.tankName.toLowerCase().includes(query)) || (x.dimensions !== null && x.dimensions.toLowerCase().includes(query)) ) } }) } // 清空筛选 const handleFilterReset = () => { setInputValue(''); setSearchFn({fn: items => {return items;}}) }; // 搜索筛选输入区域 <div> <InputSearch value={inputValue} onChange={handleSearch} /> <Button text="Reset" onClick={handleFilterReset} /> </div>
InputSearch.js
export default function InputSearch(props) { const { inputRef, name, value, error=null, onChange, ...other } = props; return ( <TextField label="Search..." name={name} value={value} onChange={onChange} {...other} {...(error && {error:true, helperText:error})} > </TextField> ) }
解决方案
1. 解决搜索延迟问题
你的handleSearch里已经用e.target.value生成查询条件,这是正确的(避免了state异步更新导致的延迟)。如果仍有延迟,检查表格渲染时是否正确调用searchFn.fn(原始数据)获取筛选结果:
// 假设原始数据是originalItems const filteredItems = searchFn.fn(originalItems); // 用filteredItems渲染表格
2. 解决重置后标签不回位+重置无反应问题
需要给输入框添加ref,重置时让输入框失去焦点,触发Material UI TextField的标签自动回位:
修改InputSearch.js,支持传入ref:
import { TextField } from '@mui/material'; import { forwardRef } from 'react'; // 用forwardRef传递ref到内部TextField const InputSearch = forwardRef((props, ref) => { const { name, value, error=null, onChange, ...other } = props; return ( <TextField ref={ref} // 绑定外部传入的ref label="Search..." name={name} value={value} onChange={onChange} {...other} {...(error && {error:true, helperText:error})} /> ) }); export default InputSearch;
修改dataTable.js,添加ref并完善重置函数:
import { useRef } from 'react'; const DataTable = () => { const [inputValue, setInputValue] = useState('') const [searchFn, setSearchFn,] = useState({ fn: items => { return items; } }); // 创建输入框ref const searchInputRef = useRef(null); // 搜索数据(保留正确逻辑,避免延迟) const handleSearch = e => { setInputValue(e.target.value) let query = e.target.value.toString().toLowerCase(); setSearchFn({ fn: items => { return query === "" ? items : items.filter(x => (x.tankName?.toLowerCase().includes(query)) || (x.dimensions?.toLowerCase().includes(query)) ) } }) } // 完善重置函数:清空值+重置筛选+输入框失焦 const handleFilterReset = () => { setInputValue(''); setSearchFn({fn: items => items}); // 让输入框失焦,触发标签回位 if (searchInputRef.current) { searchInputRef.current.blur(); } }; return ( // ...其他代码 <div> <InputSearch ref={searchInputRef} // 传入ref value={inputValue} onChange={handleSearch} /> <Button text="Reset" onClick={handleFilterReset} /> </div> // ...其他代码 ) }; export default DataTable;
关键说明
- 用
forwardRef实现父组件对输入框的焦点控制; - 重置时调用
blur()让输入框失焦,Material UI会自动根据空值+失焦状态将标签放回输入框内部; - 用
e.target.value而非inputValue生成查询条件,彻底避免state异步更新导致的延迟; - 用可选链操作符
?.简化空值判断,代码更简洁。
内容的提问来源于stack exchange,提问作者Mtullis
相关产品推荐
相关产品推荐

