fix(gifPicker): only remount grid on recents/network boundary
The viewKey added to prevent stale search cells in the recents view was
keyed on `network:${effectiveSearch}`, so it changed on every throttled
search update and category switch. Remounting the FlatList remounts its
ListHeaderComponent too, which blurred the sticky-header search input
(eating the first typed character) and caused a visible reload when
switching categories.
Drop the search term from the key — the recents bug was about crossing
the recents/network boundary, and React reconciliation handles item
changes within the network view on its own.
Addresses PR #10261 feedback from surfdude29: keyboard dismissing on
search and category-switch reload glitch.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -100,9 +100,12 @@ function GifPickerBody({
|
|||||||
const items = isRecentsActive ? getRecents() : networkItems
|
const items = isRecentsActive ? getRecents() : networkItems
|
||||||
const hasData = items.length > 0
|
const hasData = items.length > 0
|
||||||
|
|
||||||
// Remount the grid when the data source changes so FlatList doesn't carry
|
// Remount the grid only when switching between the network view and the
|
||||||
// stale virtualized cells between e.g. a search and the recents list.
|
// local recents list, so FlatList doesn't carry stale virtualized cells
|
||||||
const viewKey = isRecentsActive ? 'recents' : `network:${effectiveSearch}`
|
// across that boundary. Within the network view we rely on normal React
|
||||||
|
// reconciliation as `items` changes — remounting on every search keystroke
|
||||||
|
// would blur the sticky-header search input.
|
||||||
|
const viewKey = isRecentsActive ? 'recents' : 'network'
|
||||||
|
|
||||||
const onEndReached = () => {
|
const onEndReached = () => {
|
||||||
if (isRecentsActive) return
|
if (isRecentsActive) return
|
||||||
@@ -142,7 +145,7 @@ function GifPickerBody({
|
|||||||
<GifPickerHeader
|
<GifPickerHeader
|
||||||
inputRef={textInputRef}
|
inputRef={textInputRef}
|
||||||
onChangeText={onChangeSearch}
|
onChangeText={onChangeSearch}
|
||||||
onClose={() => control.close()}
|
onGoBack={onGoBack}
|
||||||
onEscape={() => control.close()}
|
onEscape={() => control.close()}
|
||||||
/>
|
/>
|
||||||
{showPills && (
|
{showPills && (
|
||||||
|
|||||||
@@ -16,9 +16,10 @@ type Props = {
|
|||||||
isFetchingNextPage: boolean
|
isFetchingNextPage: boolean
|
||||||
error: unknown
|
error: unknown
|
||||||
/**
|
/**
|
||||||
* Identifies the current data source (e.g. "recents", "trending", a search
|
* Identifies the current data source at a coarse grain ("recents" vs
|
||||||
* term). Used to remount the underlying FlatList when switching sources so
|
* "network"). Used to remount the underlying FlatList when crossing that
|
||||||
* virtualized cells from the previous view can't bleed into the next one.
|
* boundary so virtualized cells from the previous view can't bleed into the
|
||||||
|
* next one.
|
||||||
*/
|
*/
|
||||||
viewKey: string
|
viewKey: string
|
||||||
fetchNextPage: () => Promise<unknown>
|
fetchNextPage: () => Promise<unknown>
|
||||||
|
|||||||
Reference in New Issue
Block a user