Nested horizontal FlatList reports items as viewable while its parent row is outside the screen
還沒有人認領這個 Issue。
評估
- 難度
- 4/5
- 預估耗時
- 3-5 天
- 新手友好度
- 66/100
- Issue 類型
- 缺陷
- 描述清晰度
- 基本清楚
- 活躍度
- 活躍
- 技術堆疊
- javascript, react-native
- 領域
- mobile
研究方向
從必要的 Snack reproducer 以及使用 viewabilityConfig 和 onViewableItemsChanged 的巢狀 FlatList 設定開始。追蹤當其父列位於裝置 viewport 之外時,內部水平清單如何判定可見性。完成的標準是,首屏以下的巢狀清單不再將 item 回報為可見,而可見的巢狀 item 在 Android 和 iOS 上仍會如此回報。
由索引模型根據 Issue 內容生成。
描述
Description
System Info
React Native: 0.86.2
React: 19.2.3
React Native Gradle Plugin: 0.86.2
Node: 22.22.3
Project Node version (.nvmrc): 22.22.3
npm: 10.9.8
Yarn: 3.5.0
OS: Linux x86_64, kernel 6.8.0-136-generic
Android compile SDK: 36
Android target SDK: 36
Android min SDK: 24 (Android 7.0+)
Java: 17.0.19
Hermes: enabled
New Architecture: enabled
Expected behavior
For a horizontal FlatList nested inside a vertically scrolling FlatList, the inner list’s onViewableItemsChanged should not report an item as viewable until
the parent row is visible in the device viewport.
An item should satisfy both conditions:
Visible within the inner horizontal FlatList
AND
The parent row containing that FlatList is visible on screen
Actual behavior
onViewableItemsChanged for a nested horizontal FlatList fires when its parent row mounts, even if the parent row is below the device viewport.
The inner FlatList appears to calculate viewability relative to its own local scroll viewport only. It does not account for the outer vertical FlatList’s
clipping or whether the parent row is actually visible on the screen.
This produces false impression events for analytics: items are marked viewable before the user can see them.
Details
Our application has a vertical FlatList of sections. Several sections contain horizontal FlatLists.
On the initial screen:
Sections 1–4: visible in the device viewport
Sections 5–8: mounted by the outer FlatList but below the device viewport
The nested horizontal FlatLists in Sections 5–8 invoke onViewableItemsChanged immediately, reporting their initial items as viewable before the user scrolls
the outer list.
`import React, { useRef } from 'react';
import { FlatList, StyleSheet, Text, View } from 'react-native';
const SECTION_HEIGHT = 220;
const ITEM_WIDTH = 140;
const sections = Array.from({ length: 8 }, (_, index) => ({
id: section-${index + 1},
title: Section ${index + 1},
}));
const items = Array.from({ length: 8 }, (_, index) => ({
id: item-${index + 1},
title: Item ${index + 1},
}));
function NestedHorizontalList({ sectionId }) {
// These objects must retain their identity for the lifetime of a FlatList.
const viewabilityConfig = useRef({
itemVisiblePercentThreshold: 50,
minimumViewTime: 0,
waitForInteraction: false,
}).current;
const onViewableItemsChanged = useRef(({ viewableItems }) => {
console.log(
[${sectionId}] reported viewable before outer list is scrolled:,
viewableItems.map(({ item }) => item.id).join(', ')
);
}).current;
return (
<FlatList
horizontal
data={items}
keyExtractor={(item) => item.id}
renderItem={({ item }) => (
{item.title}
)}
viewabilityConfig={viewabilityConfig}
onViewableItemsChanged={onViewableItemsChanged}
showsHorizontalScrollIndicator={false}
/>
);
}
export default function App() {
return (
<FlatList
data={sections}
getItemLayout={(_, index) => ({
length: SECTION_HEIGHT,
offset: SECTION_HEIGHT * index,
index,
})}
keyExtractor={(item) => item.id}
renderItem={({ item }) => (
{item.title}
)}
/>
);
}
const styles = StyleSheet.create({
section: {
height: SECTION_HEIGHT,
paddingTop: 16,
borderBottomWidth: StyleSheet.hairlineWidth,
borderBottomColor: '#9ca3af',
},
sectionTitle: {
marginHorizontal: 16,
marginBottom: 12,
fontSize: 18,
fontWeight: '600',
},
item: {
width: ITEM_WIDTH,
height: 120,
marginLeft: 12,
alignItems: 'center',
justifyContent: 'center',
borderRadius: 8,
backgroundColor: '#dbeafe',
},
});`
For analytics, this is incorrect: “viewable” should represent visibility to the user, not only visibility within an off-screen nested list container.
Steps to reproduce
- Reproduction steps
- Render a vertical FlatList with multiple fixed-height rows.
- Place a horizontal FlatList inside every row.
- Add onViewableItemsChanged and viewabilityConfig to each inner horizontal FlatList.
- Launch the screen without scrolling.
- Observe that inner lists belonging to below-the-fold parent rows report items as viewable.
React Native Version
0.86.2
Affected Platforms
Runtime - Android, Runtime - iOS
Output of npx @react-native-community/cli info
System:
OS: Linux 6.8 Ubuntu 22.04.5 LTS 22.04.5 LTS (Jammy Jellyfish)
CPU: (16) x64 12th Gen Intel(R) Core(TM) i7-1270P
Memory: 13.94 GB / 30.59 GB
Shell:
version: 5.1.16
path: /bin/bash
Binaries:
Node:
version: 22.22.3
path: /home/user/.nvm/versions/node/v22.22.3/bin/node
Yarn:
version: 3.5.0
path: /home/user/.nvm/versions/node/v22.22.3/bin/yarn
npm:
version: 10.9.8
path: /home/user/.nvm/versions/node/v22.22.3/bin/npm
SDKs:
Android SDK:
API Levels: 28, 30, 31, 32, 33, 34, 35, 36
Build Tools: 36.1.0
System Images: android-36 | Google Play Intel x86_64 Atom
Android NDK: Not required for standard Expo development
Languages:
Java:
version: 17.0.19
npmPackages:
react: 19.2.3
react-native: 0.86.2
expo: ~57.0.7
Android:
hermesEnabled: true
newArchEnabled: true
Stacktrace or Logs
NA
MANDATORY Reproducer
https://snack.expo.dev/@testophobia/-nested-flatlist-viewability-repro
Screenshots and Videos
No response
- 主要語言
- C++
- 星號
- 127k
- 分支
- 25.3k
- PR 合併指標
- 30 天內沒有已合併 PR
貢獻指南
從這裡開始
- 先讀完整個 Issue,再讀專案的貢獻指南。
- 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
- Fork 儲存庫,在一個分支上完成修改。
- 送出 Pull Request,並在描述裡引用這個 Issue 編號。
react/react-native 的其他 Issue
-
Needs: Author Feedback Needs: Repro
難度 1/5 1 小時以內 新手友好度 92/100
react/react-native#58621 · 1 則留言 ·
-
Needs: Author Feedback Needs: Repro
難度 2/5 1-3 小時 新手友好度 85/100
react/react-native#58610 · 1 則留言 ·
-
Needs: Triage :mag:
難度 2/5 1-3 小時 新手友好度 82/100
react/react-native#58565 · 1 則留言 · 2 個 reaction ·
-
Needs: Author Feedback Needs: Repro
難度 2/5 1-3 小時 新手友好度 88/100
react/react-native#58555 · 5 則留言 · 2 個 reaction ·
-
Needs: Attention Needs: Repro
難度 2/5 1-3 小時 新手友好度 85/100
react/react-native#58526 · 2 則留言 ·
查看 react/react-native 的全部 Issue
相似的 Issue
-
難度 2/5 1-3 小時 新手友好度 75/100
flutter-webrtc/flutter-webrtc#2206 ·
-
難度 2/5 1-3 小時 新手友好度 70/100
google-ai-edge/LiteRT-LM#3739 ·
-
Component: GLib
難度 2/5 1-3 小時 新手友好度 70/100
-
難度 2/5 1-3 小時 新手友好度 65/100
brave/brave-browser#59300 ·
-
Mute ydb/tests/functional/dstool/test_canonical_requests.py.Test.test_group_take_snapshot in main 未關閉ai_reviewed
難度 2/5 1-3 小時 新手友好度 70/100
ydb-platform/ydb#53974 · 3 則留言 ·