Closed MANDT-SYS closed 3 months ago
Hey @MANDT-SYS you are entering an infinite loop because every state change will change the reference to rows and therefore enter the handleStateChange
again.
May I ask why you need to store the rows in state?
Thank you for your response. I need to perform aggregations on the filtered data and export it to Excel (using ExcelJs for the Excel export).
We do support aggregation and export to excel as well... wouldn't that be an option?
Thank you for your response.
I am aware that both are feasible with the Premium plan.
However, what I am hoping for is something unique and in a way that is possible within the scope of the Pro plan.
I have the following two ideas for the use of state
Sorry for the lack of explanation.
In that case you can certainly use an external state, but be aware that every state update brings a rerender to the complete data grid. This means you will essentially loose quite a bit of the performance improvements.
The main problem you are facing is that you are updating the state on every state change of the grid. This is why you are running into the infinite loop.
If you need only the filtered rows we do have a getFilterState
function that returns the current filterState. Or you can use the handleStateChange
function, but extract the data needed and keep the rows state consistent.
I would advise you to do something similar to this:
import * as React from 'react';
import { DataGrid, GridToolbar, useGridApiContext, useGridApiRef } from '@mui/x-data-grid';
import { useDemoData } from '@mui/x-data-grid-generator';
import { Stack } from '@mui/material';
const VISIBLE_FIELDS = ['name', 'rating', 'country', 'salary'];
const AggregatedValues = (props) => {
const { gridApiRef } = props;
React.useEffect(() => {
if (gridApiRef.current == null) {
return;
}
gridApiRef.current.subscribeEvent('filterModelChange', (event) => {
console.log('filter model change', event);
console.log(gridApiRef.current.getFilterState(event));
});
}, [gridApiRef]);
return <div>Aggregated values</div>;
};
export default function BasicExampleDataGrid() {
const apiRef = useGridApiRef();
const { data } = useDemoData({
dataSet: 'Employee',
visibleFields: VISIBLE_FIELDS,
rowLength: 100,
});
const handleStateChange = React.useCallback(
(newState) => {
// do something with the state here
},
[apiRef],
);
return (
<Stack spacing={2}>
<div style={{ height: 400, width: '100%' }}>
<DataGrid
{...data}
apiRef={apiRef}
slots={{ toolbar: GridToolbar }}
onStateChange={handleStateChange}
/>
</div>
<AggregatedValues gridApiRef={apiRef} />
</Stack>
);
}
This way you can utilize the grids performant filtering and sorting and on the other hand can access the internal state for outside computations.
Would that be a good starting point for you?
Thank you for your response.
I tried to display the code as you provided, but could not run the filter to see how it works.
gridApiRef.current.getFilterState(event) The following error is occurring in the section TypeError: gridApiRef.current.getFilterState is not a function
////////////////////////////////////////////////////////////////////////////////////////////
The code provided was not executable, but I found another solution. When updating the state in the handleStateChange function, it is compared to the original value.
setFilteredData((prevData) => {
const prevKeys = prevData.map((row) => row.id)
const newKeys = rows.map((row) => row.id)
if (JSON.stringify(prevKeys) ! == JSON.stringify(newKeys)) {
return rows
}
return prevData
})
By doing this, we were able to save to state without an infinite loop.
getFilterState
just recently got released, so you would need to use v7.7.1 for it.
your comparison method will work, yes. But I would still strongly advise to use the internal state of the grid for performance reasons.
Thank you for your reply.
Understood. Thank you for your help in resolving the issue.
Thank you again.
@MANDT-SYS is this issue resolved for you? Or do you need some additional help?
:warning: This issue has been closed. If you have a similar problem but not exactly the same, please open a new issue. Now, if you have additional information related to this issue or things that could help future readers, feel free to leave a comment.
@MANDT-SYS: How did we do? Your experience with our support team matters to us. If you have a moment, please share your thoughts in this short Support Satisfaction survey.
The problem in depth
Thank you for all your help.
I am currently using DataGridPro. I would like to save the results of filtering with GridToolbarQuickFilter and GridToolbarFilterButton set in CustomToolbar to state. How can I do that?
By the way, I read and tried the issue #11729. It was possible to display the filtered data in console.log, but when I save it to state and display it in console.log, I get an infinite loop.
Please reply.
Your environment
System: OS: Windows 11 10.0.22631 Binaries: Node: 18.16.0 - C:\Program Files\nodejs\node.EXE npm: 9.5.1 - C:\Program Files\nodejs\npm.CMD pnpm: Not Found Browsers: Chrome: Not Found Edge: Chromium (126.0.2592.61) npmPackages: @emotion/react: ^11.10.4 => 11.10.4 @emotion/styled: ^11.10.4 => 11.10.4 @mui/base: 5.0.0-alpha.100 @mui/core-downloads-tracker: 5.10.8 @mui/icons-material: ^5.10.6 => 5.10.6 @mui/material: ^5.10.8 => 5.10.8 @mui/private-theming: 5.10.6 @mui/styled-engine: 5.10.8 @mui/system: 5.10.8 @mui/types: 7.2.4 @mui/utils: 5.13.1 @mui/x-data-grid: ^5.17.8 => 5.17.8 @mui/x-data-grid-generator: ^6.6.0 => 6.6.0 @mui/x-data-grid-premium: 6.6.0 @mui/x-data-grid-pro: ^6.6.0 => 6.6.0 @mui/x-date-pickers: ^5.0.5 => 5.0.5 @mui/x-date-pickers-pro: ^6.6.0 => 6.6.0 @mui/x-license-pro: 6.6.0 @types/react: ^18.0.18 => 18.0.18 react: ^18.2.0 => 18.2.0 react-dom: ^18.2.0 => 18.2.0 typescript: ^4.8.2 => 4.8.2
Search keywords: data grid filter get Order ID: 68259