React Native中如何在ScrollView内使用FlatList并解决相关报错
报错原因
同滚动方向的ScrollView嵌套FlatList(本质是VirtualizedList的封装)时,会破坏FlatList的窗口化渲染机制,导致所有列表项一次性渲染,严重损耗性能,还会触发滚动手势冲突,因此React Native框架做了强制报错提示。
可行解决方案
方案1:小数据量直接替换FlatList
如果你的data列表项数量不多(少于30条),直接删掉FlatList,用数组map遍历渲染列表项即可,完全规避嵌套问题:
<ScrollView onScroll={(e) => { onScroll(e); }} stickyHeaderIndices={[1]} contentContainerStyle={{ flexGrow: 1, justifyContent: 'center' }} style={{ width: '100%' }} > <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center', }}> {isLoading ? ( <DotIndicator color="#4cd137" style={{ marginBottom: 200 }} /> ) : ( data.map((item, index) => ( <View key={String(index)} style={{ flex: 0, padding: 5, }}> <Card style={styles.card}> <CardItem header style={styles.cardText}> <Title style={styles.textSign}>{item.question}</Title> </CardItem> <CardItem style={styles.cardText1}> <Body> <Paragraph>{item.answer}</Paragraph> </Body> </CardItem> </Card> </View> )) )} </View> </ScrollView>
方案2:保留嵌套结构禁用内层滚动
如果必须保留现有结构,给FlatList添加两个属性即可关闭报错,注意此方案仍会丢失窗口化优势,仅适合小数据量场景:
<FlatList data={data} scrollEnabled={false} // 禁用内层滚动,交给外层ScrollView处理 nestedScrollEnabled={true} // 开启嵌套滚动支持 keyExtractor={(item, index) => String(index)} renderItem={({ item }) => /* 原有渲染逻辑不变 */} />
方案3(最推荐):移除外层ScrollView,改用FlatList原生能力实现需求
FlatList本身支持头部、尾部自定义插入内容,也支持吸顶配置,完全可以替代外层ScrollView的能力,同时保留窗口化渲染的性能优势:
{isLoading ? ( <DotIndicator color="#4cd137" style={{ flex: 1, marginBottom: 200, alignSelf: 'center' }} /> ) : ( <FlatList data={data} onScroll={(e) => { onScroll(e); }} stickyHeaderIndices={[1]} // 直接配置吸顶序号,对应ListHeaderComponent里的第2个子元素 contentContainerStyle={{ flexGrow: 1, justifyContent: 'center' }} style={{ width: '100%' }} // 把原来ScrollView里除了列表之外的内容放到ListHeaderComponent ListHeaderComponent={ <View style={{ alignItems: 'center', justifyContent: 'center', }}> {/* 这里放你原来ScrollView里FlatList之前的所有其他内容 */} </View> } keyExtractor={(item, index) => String(index)} renderItem={({ item }) => /* 原有渲染逻辑不变 */} /> )}
内容的提问来源于stack exchange,提问作者Danuja
相关产品推荐
相关产品推荐

