Issue
I am using react-query
for data fetching in React Native
. I have a Notifications screen. In this screen there are two queries
- useGrocerNotifications -> returns last 10 notifications
- useGrocerAllNotifications -> returns all notifications that includes last 10 notifications too
Note: these queries have different urls and query keys
useGrocerAllNotifications
query is disabled by default. There is a button in page that called Load All
. When user click this button I enable the useGrocerAllNotifications
query and update FlatList
data but it sometimes does not rerender.
Here is my code
Notifications.tsx
export function GrocerNotifications() {
const [isPressedLoadAll, setIsPressedLoadAll] = useState(false)
const queryClient = useQueryClient()
const { data, refetch, isFetching } = useGrocerNotifications()
const {
data: allData,
refetch: allRefetch,
isFetching: isAllFetching
} = useGrocerAllNotifications({
enabled: isPressedLoadAll
})
const renderData = useMemo(() => {
if (Array.isArray(allData) && allData.length > 0 && isPressedLoadAll) return allData
if (Array.isArray(data) && data.length > 0) return data
return []
}, [allData, data, isPressedLoadAll])
const contentContainerStyle = useBottomSafeStyle(styles.contentContainer)
const handleLoadAllPress = useCallback(() => {
queryClient.invalidateQueries({ queryKey: ['grocer', 'notifications', 'all'] })
setIsPressedLoadAll(true)
}, [queryClient])
const renderItem: ListRenderItem<GrocerNotificationType> = useCallback(
({ item }) => (
<GrocerNotification
title={item.title}
description={item.description}
date={item.createdDate}
isNew={!item.isRecieved}
/>
),
[]
)
const keyExtractor = useCallback(
(item: GrocerNotificationType) => `grocer_notification_${item.id}`,
[]
)
const handleRefresh = useCallback(() => {
if (isPressedLoadAll) {
allRefetch()
return
}
refetch()
}, [refetch, allRefetch, isPressedLoadAll])
return (
<FlatList
data={renderData}
renderItem={renderItem}
style={styles.flatList}
contentContainerStyle={contentContainerStyle}
keyExtractor={keyExtractor}
refreshing={isFetching || isAllFetching}
onRefresh={handleRefresh}
/>
)
}
Data is updating correctly. I can see new data in console but it is not reflecting to FlatList
There is something wrong but I do not know what it is.
Here are the console logs
old data:
[
{
"id": 48,
"title": "7 kasım aykut 9"
},
{
"id": 47,
"title": "7 kasım aykut 8"
},
{
"id": 46,
"title": "7 kasım aykut 7"
},
{
"id": 45,
"title": "7 kasım aykut 6"
},
{
"id": 44,
"title": "7 kasım aykut 5"
},
{
"id": 43,
"title": "7 kasım aykut 4"
},
{
"id": 42,
"title": "7 kasım aykut 3"
},
{
"id": 41,
"title": "7 kasım aykut 2"
},
{
"id": 40,
"title": "7 kasım aykut 1"
},
{
"id": 39,
"title": "6 kasım aykut 3"
}
]
new data:
[
{
"id": 48,
"title": "7 kasım aykut 9"
},
{
"id": 47,
"title": "7 kasım aykut 8"
},
{
"id": 46,
"title": "7 kasım aykut 7"
},
{
"id": 45,
"title": "7 kasım aykut 6"
},
{
"id": 44,
"title": "7 kasım aykut 5"
},
{
"id": 43,
"title": "7 kasım aykut 4"
},
{
"id": 42,
"title": "7 kasım aykut 3"
},
{
"id": 41,
"title": "7 kasım aykut 2"
},
{
"id": 40,
"title": "7 kasım aykut 1"
},
{
"id": 39,
"title": "6 kasım aykut 3"
},
{
"id": 38,
"title": "6 kasım aykut 2"
},
{
"id": 35,
"title": "6 kasım aykut 1"
}
]
as you can see there are 2 new items with ids 38 and 35
but FlatList
keyExtractor
behaves strangely
Here are keyExtractor
logs
old keyExtractor data:
runs twice on mount I do not know why
{
"id": 48,
"title": "7 kasım aykut 9"
}
{
"id": 47,
"title": "7 kasım aykut 8"
}
{
"id": 46,
"title": "7 kasım aykut 7"
}
{
"id": 45,
"title": "7 kasım aykut 6"
}
{
"id": 44,
"title": "7 kasım aykut 5"
}
{
"id": 43,
"title": "7 kasım aykut 4"
}
{
"id": 42,
"title": "7 kasım aykut 3"
}
{
"id": 41,
"title": "7 kasım aykut 2"
}
{
"id": 40,
"title": "7 kasım aykut 1"
}
{
"id": 39,
"title": "6 kasım aykut 3"
}
{
"id": 48,
"title": "7 kasım aykut 9"
}
{
"id": 47,
"title": "7 kasım aykut 8"
}
{
"id": 46,
"title": "7 kasım aykut 7"
}
{
"id": 45,
"title": "7 kasım aykut 6"
}
{
"id": 44,
"title": "7 kasım aykut 5"
}
{
"id": 43,
"title": "7 kasım aykut 4"
}
{
"id": 42,
"title": "7 kasım aykut 3"
}
{
"id": 41,
"title": "7 kasım aykut 2"
}
{
"id": 40,
"title": "7 kasım aykut 1"
}
{
"id": 39,
"title": "6 kasım aykut 3"
}
new keyExtractor data:
runs twice too
{
"id": 48,
"title": "7 kasım aykut 9"
}
{
"id": 47,
"title": "7 kasım aykut 8"
}
{
"id": 46,
"title": "7 kasım aykut 7"
}
{
"id": 45,
"title": "7 kasım aykut 6"
}
{
"id": 44,
"title": "7 kasım aykut 5"
}
{
"id": 43,
"title": "7 kasım aykut 4"
}
{
"id": 42,
"title": "7 kasım aykut 3"
}
{
"id": 41,
"title": "7 kasım aykut 2"
}
{
"id": 40,
"title": "7 kasım aykut 1"
}
{
"id": 39,
"title": "6 kasım aykut 3"
}
{
"id": 38,
"title": "6 kasım aykut 2"
}
{
"id": 39, -> what happens here. Why does id 39 come again. This should be id 35 according to data
"title": "6 kasım aykut 3"
}
after this the data seems to revert back to old one ??
{
"id": 48,
"title": "7 kasım aykut 9"
}
{
"id": 47,
"title": "7 kasım aykut 8"
}
{
"id": 46,
"title": "7 kasım aykut 7"
}
{
"id": 45,
"title": "7 kasım aykut 6"
}
{
"id": 44,
"title": "7 kasım aykut 5"
}
{
"id": 43,
"title": "7 kasım aykut 4"
}
{
"id": 42,
"title": "7 kasım aykut 3"
}
{
"id": 41,
"title": "7 kasım aykut 2"
}
{
"id": 40,
"title": "7 kasım aykut 1"
}
{
"id": 39,
"title": "6 kasım aykut 3"
}
I have tried these solutions
- adding
extraData
prop withrenderData
renderData.length
allData
allData.length
isPressedLoadAll
- fetch data without
react-query
and save data to one local state
No luck. FlatList data sometimes not updating.
Can someone explain what happening here?
Solution
I upgraded react-native version from 0.71.7 to 0.72.6. Looks like the problem has been fixed.
Answered By - AuroPick
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.