Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions src/components/SelectionListWithModal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,21 +46,26 @@ function SelectionListWithModal<TItem extends ListItem>({
// This gives FlashList time to properly update its layout cache when searching/filtering
const [, debouncedData, setDataState] = useDebouncedState<TItem[]>(data, CONST.TIMING.SEARCH_OPTION_LIST_DEBOUNCE_TIME);

// Determine if this is changed by filtering (to limit multiple rerenders)
const isFiltering = data.length < debouncedData.length;
Comment on lines +49 to +50

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Debounce skips when filter keeps same length

The new isFiltering heuristic only treats filtering as “length decreases.” If a search query changes the list contents without changing length (or when clearing a filter increases length), displayData will use the immediate data and bypass the debounce. That reintroduces the rapid update behavior the debounce was added to prevent (FlashList layout cache errors), but now only for those common filtering cases. Consider tying the debounce to actual filter/query changes rather than data.length.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm aware of that, however we don't want to slow down the process when the user is adding new items, e.g. tags.
I believe that debouncing the data when the user is entering a filter will be enough


useEffect(() => {
setDataState(data);
}, [data, setDataState]);

const displayData = isFiltering ? debouncedData : data;

const selectedItems = useMemo(
() =>
selectedItemsProp ??
debouncedData.filter((item) => {
displayData.filter((item) => {
if (isSelected) {
return isSelected(item);
}
return !!item.isSelected;
}) ??
[],
[isSelected, debouncedData, selectedItemsProp],
[isSelected, displayData, selectedItemsProp],
);

useHandleSelectionMode(selectedItems);
Expand Down Expand Up @@ -96,7 +101,7 @@ function SelectionListWithModal<TItem extends ListItem>({
<>
<SelectionList
ref={ref}
data={debouncedData}
data={displayData}
addBottomSafeAreaPadding
selectedItems={selectedItemsProp}
onLongPressRow={handleLongPressRow}
Expand Down
Loading