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.
The easiest way to update data inside the grid is to replace the data you gave it with a fresh set of data. This is done by either updating the rowData bound property (if using a framework) or calling api. setRowData(newData) . See Updating Row Data for more details.
Adding/removing columns from column definitions We can add or remove columns in our grid by updating the columnDefs property, passing in a new set of column definitions. Columns that didn't exist previously will be added to the grid. Columns that are not included in the new set will be removed from the grid.
There is a way you can achieve this. Have a flag for ngIf at the ag-grid-angular element level, and conditionally toggle it inside your event handler. This way, the grid will be reinitialised with the updated flag. Keep in mind that there is a performance cost involved here as the grid is being reinitialised.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With