问题
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.
回答1:
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
来源:https://stackoverflow.com/questions/58561095/use-state-variable-in-ag-grid-callback-not-updating