React中如何获取AG Grid过滤器的用户输入值?
问题原因
onFilterChanged 是AG Grid的过滤条件应用完成后才会触发的网格级事件:
- 事件对象本身不携带过滤器输入框的键入内容
- 默认配置下,文本过滤器输入后存在500ms防抖,且需要用户按回车/输入框失焦才会正式提交过滤条件,因此既无法拿到实时输入值,也无法直接从事件回调中取到过滤内容。
方案1:仅需获取最终生效的过滤值
如果不需要逐键监听输入,只需要拿到用户确认后的过滤条件,不需要改过滤器逻辑,直接在事件回调中通过网格API读取过滤模型即可:
- 首先给
AgGridReact组件绑定ref
import { useRef, useMemo } from 'react'; import type { AgGridReact as AgGridReactType } from 'ag-grid-react'; // 组件内声明ref const gridRef = useRef<AgGridReactType>(null); // 调整defaultColDef配置,可修改过滤触发时机 const defaultColDef = useMemo(() => ({ // 保留你原来的defaultColDef配置,比如sortable、filterable等 filterParams: { debounceMs: 0, // 输入后立刻触发过滤,不需要等待默认的500ms防抖 suppressEnterKey: true, // 不需要按回车触发过滤 } }), []);
- 在
onFilterChanged中读取过滤模型
<AgGridReact ref={gridRef} rowData={all.flat().reverse()} columnDefs={columnDefs} groupIncludeFooter={true} groupIncludeTotalFooter={true} defaultColDef={defaultColDef} animateRows={true} onFilterChanged={() => { // 获取所有列当前生效的过滤规则 const allFilterValues = gridRef.current?.api.getFilterModel(); console.log('当前生效的过滤条件', allFilterValues); // 比如要读field为"username"列的输入值,直接取allFilterValues.username?.filter即可 }} ></AgGridReact>
方案2:需要逐键实时监听输入值(和普通input onChange效果一致)
如果需要拿到用户每一次敲击键盘输入的内容,不受AG Grid默认过滤提交逻辑、防抖逻辑限制,最稳定的方式是自定义文本过滤器:
- 先实现自定义过滤器组件
import { useState, useEffect } from 'react'; const RealTimeTextFilter = (props) => { const [inputVal, setInputVal] = useState(''); // 输入事件,和普通input的onChange逻辑完全一致 const handleInput = (e) => { const currentValue = e.target.value; setInputVal(currentValue); // 这里可以直接拿到每一次键入的实时值 console.log('用户实时输入内容:', currentValue); // 通知AG Grid过滤条件更新 props.filterChangedCallback(); }; // 以下是AG Grid过滤器要求实现的标准方法 const doesFilterPass = (params) => { if (!inputVal) return true; // 自定义匹配规则,这里是不区分大小写的包含匹配 return params.data[props.colDef.field] ?.toString() .toLowerCase() .includes(inputVal.toLowerCase()); }; const isFilterActive = () => inputVal.trim() !== ''; const getModel = () => isFilterActive() ? { filterType: 'text', type: 'contains', filter: inputVal } : null; const setModel = (model) => setInputVal(model?.filter || ''); useEffect(() => { props.filterModifiedCallback(); }, [inputVal]); return ( <div style={{ padding: '6px' }}> <input type="text" value={inputVal} onChange={handleInput} placeholder="输入关键词搜索" style={{ width: '100%', padding: '3px 6px', boxSizing: 'border-box' }} /> </div> ); };
- 在列配置中启用自定义过滤器
const defaultColDef = useMemo(() => ({ // 你原来的其他配置 filter: RealTimeTextFilter, // 替换默认过滤器为自定义实时过滤器 }), []);
注意事项
- 不要通过原生DOM选择器查找
.ag-filter-input类名绑定事件,AG Grid版本迭代时可能调整DOM结构和类名,会导致逻辑失效。 - 方案1性能更好,适合绝大多数只需要拿过滤结果的场景;方案2灵活度最高,适合需要实时响应输入的场景,比如输入联想、实时搜索埋点等需求。
内容的提问来源于stack exchange,提问作者taha maatof
相关产品推荐
相关产品推荐

