-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[DataGrid] Fix quick filter input lag #9630
Conversation
Netlify deploy previewNetlify deploy preview: https://deploy-preview-9630--material-ui-x.netlify.app/ Updated pagesNo updates. These are the results for the performance tests:
|
@@ -101,7 +101,9 @@ function GridToolbarQuickFilter(props: GridToolbarQuickFilterProps) { | |||
|
|||
const updateSearchValue = React.useCallback( | |||
(newSearchValue: string) => { | |||
apiRef.current.setQuickFilterValues(quickFilterParser(newSearchValue)); | |||
const newQuickFilterValues = quickFilterParser(newSearchValue); | |||
setPrevQuickFilterValues(newQuickFilterValues); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The root cause of this issue was here:
mui-x/packages/grid/x-data-grid/src/components/toolbar/GridToolbarQuickFilter.tsx
Lines 88 to 100 in b083f58
React.useEffect(() => { | |
if (!isDeepEqual(prevQuickFilterValues, quickFilterValues)) { | |
// The model of quick filter value has been updated | |
setPrevQuickFilterValues(quickFilterValues); | |
// Update the input value if needed to match the new model | |
setSearchValue((prevSearchValue) => | |
isDeepEqual(quickFilterParser(prevSearchValue), quickFilterValues) | |
? prevSearchValue | |
: quickFilterFormatter(quickFilterValues ?? []), | |
); | |
} | |
}, [prevQuickFilterValues, quickFilterValues, quickFilterFormatter, quickFilterParser]); |
Here is what was happening:
- type 'a':
setSearchValue('a')
- debounced
setQuickFilterValues(['a'])
is called - type 'b':
setSearchValue('ab')
- useEffect:
prevQuickFilterValues /* [] */ !== quickFilterValues /* ['a'] */
, reset search value:setSearchValue('a')
- type 'c':
setSearchValue('ac')
// b was lost in the previous step
We should update prevQuickFilterValues
as well when updating quickFilterValues
internally.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems that prevQuickFilterValues
should be a ref instead, what do you think? We only use it to ensure that the effect above only runs when quickFilterValues
changes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point, it should be a ref indeed!
if (isJSDOM) { | ||
this.skip(); | ||
} | ||
// Warning: this test doesn't fail consistently as it is timing-sensitive. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While this test doesn't consistently fail without the fix, I thought it was still better than nothing 🙂
What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not ideal but it's fine as it is.
@@ -59,7 +59,7 @@ export type GridToolbarQuickFilterProps = TextFieldProps & { | |||
* @param {any[]} values The new values passed to the quick filter model | |||
* @returns {string} The string to display in the text field | |||
*/ | |||
quickFilterFormatter?: (values: GridFilterModel['quickFilterValues']) => string; | |||
quickFilterFormatter?: (values: NonNullable<GridFilterModel['quickFilterValues']>) => string; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We never pass undefined
as values
, so we should exclude it here
This pull request has conflicts, please resolve those before we can evaluate the pull request. |
@@ -101,7 +101,9 @@ function GridToolbarQuickFilter(props: GridToolbarQuickFilterProps) { | |||
|
|||
const updateSearchValue = React.useCallback( | |||
(newSearchValue: string) => { | |||
apiRef.current.setQuickFilterValues(quickFilterParser(newSearchValue)); | |||
const newQuickFilterValues = quickFilterParser(newSearchValue); | |||
setPrevQuickFilterValues(newQuickFilterValues); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems that prevQuickFilterValues
should be a ref instead, what do you think? We only use it to ensure that the effect above only runs when quickFilterValues
changes.
Fixes #6783
Before: https://codesandbox.io/s/infallible-villani-gmwpg6
After: https://codesandbox.io/s/long-tree-q7p8c9