在 ag 网格回调中使用状态变量未更新 [英] Use state variable in ag grid callback not updating
问题描述
我在函数isExternalFilterPresent
内使用状态变量query
从不更新.我很困惑,因为 query
的第一个 console.log
会随着查询的每次更改而更新.我想这是因为我不太了解钩子的实现.
let gridApi: GridApi |空 = 空;const HouseholdTable = ({accountsData, aggregateEntityTable: {aggregateEntity, columnDefs}}: OwnProps & StateProps) =>{const [isDeepDiveOpen, setIsDeepDiveOpen] = useState(false);const [查询,setQuery] = useState('');useEffect(() => {gridApi &&gridApi.onFilterChanged();}, [询问]);如果(帐户数据){const onGridReady = ({api}: GridReadyEvent) =>{api.sizeColumnsToFit();gridApi = api;};const aggData = accountsData.aggregations[aggregateEntity];控制台日志(查询);//当查询改变时更新const isExternalFilterPresent = (): boolean =>{控制台日志(查询);//这永远不会更新返回!!查询;};const doExternalFilterPass = (rowNode: RowNode): boolean =>{//console.log('doesExternalFilterPass');返回真;};返回 (<><HouseholdsToolbar aggData={aggData}isDeepDiveOpen={isDeepDiveOpen}onDeepDiveToggleClick={setIsDeepDiveOpen}onQueryChange={setQuery}/><AgGridReact rowData={[]}columnDefs={[]}网格选项={{标头高度:70,抑制FieldDotNotation:真,抑制水平滚动:假,onGridReady,isExternalFilterPresent,外部过滤器通过}}/></>);} 别的 {//处理加载返回(<div>加载</div>);}};const mapStateToProps = (state: StoreState): StateProps =>{const {faStore: {accountsData}} = 状态;返回 {帐户数据,聚合实体表:聚合实体表虚拟配置};};导出默认连接(mapStateToProps)(HouseholdTable);导出 constaggregateEntityTableDummyConfig:AggregateEntityTable = {聚合实体:'FOO',列定义:[]};
更新了整个组件.
hook 不是问题.看起来在第一次渲染时 AgGridReact
存储对您传递给 isExternalFilterPresent
的函数的引用,然后在重新渲染时永远不会更改此引用.更清楚地说,AgGridReact
存储了 isExternalFilterPresent
的第一个版本"并且从不更新它.要解决您的问题,您需要将过滤器的值存储在 useRef
钩子中.
React 文档 说:
<块引用>useRef() 钩子不仅仅用于 DOM 引用.ref"对象是一个通用容器,其当前属性是可变的,可以保存任何值,类似于类的实例属性.
所以你可能会认为 useRef 就像类中的属性一样.
这是你必须做的:
const query = useRef(null);const setQuery = (value) =>{query.current = 值;gridApi &&gridApi.onFilterChanged();}const isExternalFilterPresent = (): boolean =>{控制台日志(查询.当前);//现在变了返回 !!query.current;};
这里有一个关于 codesandbox
My use state variable, query
, inside of the function isExternalFilterPresent
never updates. I'm perplexed because the first console.log
of query
updates with each change of query. I think this is because I'm not quite understand the implementation of hooks.
let gridApi: GridApi | null = null;
const HouseholdTable = ({accountsData, aggregateEntityTable: {aggregateEntity, columnDefs}}: OwnProps & StateProps) => {
const [isDeepDiveOpen, setIsDeepDiveOpen] = useState(false);
const [query, setQuery] = useState('');
useEffect(() => {
gridApi && gridApi.onFilterChanged();
}, [query]);
if (accountsData) {
const onGridReady = ({api}: GridReadyEvent) => {
api.sizeColumnsToFit();
gridApi = api;
};
const aggData = accountsData.aggregations[aggregateEntity];
console.log(query); // This updates when query changes
const isExternalFilterPresent = (): boolean => {
console.log(query); // This never updates
return !!query;
};
const doesExternalFilterPass = (rowNode: RowNode): boolean => {
// console.log('doesExternalFilterPass');
return true;
};
return (
<>
<HouseholdsToolbar aggData={aggData}
isDeepDiveOpen={isDeepDiveOpen}
onDeepDiveToggleClick={setIsDeepDiveOpen}
onQueryChange={setQuery}
/>
<AgGridReact rowData={[]}
columnDefs={[]}
gridOptions={{
headerHeight: 70,
suppressFieldDotNotation: true,
suppressHorizontalScroll: false,
onGridReady,
isExternalFilterPresent,
doesExternalFilterPass
}}
/>
</>
);
} else {
// handle loading
return (<div>loading</div>);
}
};
const mapStateToProps = (state: StoreState): StateProps => {
const {faStore: {accountsData}} = state;
return {
accountsData,
aggregateEntityTable: aggregateEntityTableDummyConfig
};
};
export default connect(mapStateToProps)(HouseholdTable);
export const aggregateEntityTableDummyConfig: AggregateEntityTable = {
aggregateEntity: 'FOO',
columnDefs: []
};
EDIT: Updated with the entire component.
It is not a problem with hooks. It looks like on the first rendering AgGridReact
stores the reference to a function that you pass to isExternalFilterPresent
and then never changes this reference on re-renders. To be more clear, AgGridReact
stores the first 'version' of isExternalFilterPresent
and never updates it. To fix your problem, you need to store the value of your filter in useRef
hook.
React doc says:
The useRef() Hook isn’t just for DOM refs. The "ref" object is a generic container whose current property is mutable and can hold any value, similar to an instance property on a class.
So you might think about useRef like about property in the class.
Here what you have to do:
const query = useRef(null);
const setQuery = (value) => {
query.current = value;
gridApi && gridApi.onFilterChanged();
}
const isExternalFilterPresent = (): boolean => {
console.log(query.current); // Now it changes
return !!query.current;
};
Here an example on codesandbox
这篇关于在 ag 网格回调中使用状态变量未更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!