问题
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