fix(review): derive filter sheet pages from live query data, keep reset handler over forwarded props

This commit is contained in:
Gauvain
2026-07-17 17:44:16 +02:00
parent d2db319593
commit 0202c1caa9
2 changed files with 10 additions and 20 deletions

View File

@@ -18,9 +18,10 @@ export const ResetFiltersButton: React.FC<Props> = ({
return (
<TouchableOpacity
onPress={resetAllFilters}
className='bg-purple-600 rounded-full w-[30px] h-[30px] flex items-center justify-center mr-1'
{...props}
// After the spread so a forwarded onPress can't disable the reset.
onPress={resetAllFilters}
>
<Ionicons name='close' size={20} color='white' />
</TouchableOpacity>

View File

@@ -167,7 +167,6 @@ const SharedFilterSheetContent: React.FC<SharedFilterSheetContentProps> = ({
enabled: !!id && !!queryFn && !!queryKey,
});
const [data, setData] = useState<any[]>([]);
const [offset, setOffset] = useState(0);
const [search, setSearch] = useState("");
@@ -187,6 +186,14 @@ const SharedFilterSheetContent: React.FC<SharedFilterSheetContentProps> = ({
return results.slice(0, 100);
}, [deferredSearch, _data, searchFilter]);
// Paginated window derived from the live query result ("load more" grows the
// window). No accumulated copy: a background refetch that removes options
// can't leave stale rows behind, and no per-item dedupe is needed.
const data = useMemo(
() => _data?.slice(0, offset + LIMIT) ?? [],
[_data, offset],
);
useEffect(() => {
if (!data || data.length === 0 || disableSearch) return;
if (data.length > 15) {
@@ -194,24 +201,6 @@ const SharedFilterSheetContent: React.FC<SharedFilterSheetContentProps> = ({
}
}, [data, disableSearch]);
// Loads data in batches of LIMIT from offset (efficient "load more").
useEffect(() => {
if (!_data || _data.length === 0) return;
const newData = [...data];
for (let i = offset; i < Math.min(_data.length, offset + LIMIT); i++) {
const item = _data[i];
// Option objects are recreated across renders → dedupe by value.
const exists = newData.some((existingItem) =>
isEqual(existingItem, item),
);
if (!exists) {
newData.push(item);
}
}
setData(newData);
}, [offset, _data]);
const renderData = useMemo(() => {
if (deferredSearch.length > 0 && showSearch) return filteredData;
return data;