打开Dropdown报VirtualizedLists should never be nested inside plain ScrollViews无法操作怎么办
报错原因
VirtualizedLists should never be nested inside plain ScrollViews 是React Native原生抛出的警告,根因如下:
- 你当前页面根容器使用了普通
ScrollView,而所用Dropdown组件的下拉选项列表默认基于FlatList实现,FlatList是VirtualizedList的派生组件 - 普通ScrollView和VirtualizedList的滚动事件机制存在冲突:两者会抢占触摸响应权,导致内部VirtualizedList无法正确计算可视区域高度、滚动事件被外层拦截,最终触发你遇到的下拉选项无法滚动、点击选中失效的问题。
解决方案
可根据实际业务场景选择对应方案:
方案1:替换外层ScrollView为FlatList(性能最优,最推荐)
将当前根容器ScrollView改为FlatList,把表单渲染逻辑放到renderItem回调中,底部按钮放到ListFooterComponent中,外层本身为虚拟滚动容器,不会和Dropdown内部的虚拟列表产生冲突,改造示例代码如下:
<FlatList data={formSchema} keyExtractor={(item, index) => index.toString()} renderItem={({ item: field }) => { const { name, label, type } = field; if (type === 'select') { return ( <View style={styles.dropdownWrapper} key={index}> <Dropdown /> </View> ); } if (type === 'input') { return ( <View style={styles.wrapper}> <Input name={name} label={label} /> </View> ); } }} ListFooterComponent={() => ( <View style={{ ...styles.controls, backgroundColor: '#242424', }}> <View style={styles.wrapper}> <Button onPress={() => ()} /> </View> <View style={styles.wrapper}> <Button text="Go" /> </View> </View> )} />
方案2:关闭Dropdown内部虚拟滚动
主流第三方Dropdown组件基本都提供了关闭虚拟列表的配置项,比如react-native-element-dropdown可添加virtual={false}属性,其他组件可查找对应配置参数(一般命名为virtualized、useVirtualList等),关闭后内部选项会用普通View/ScrollView渲染,不会和外层ScrollView冲突。
注意:如果Dropdown选项数量超过50个,该方案会产生性能损耗,优先选择方案1
方案3:开启Dropdown的全局挂载能力
如果所用Dropdown支持portal配置,开启后下拉弹窗会脱离当前ScrollView的节点层级,直接挂载到应用根节点下,自然不会被外层ScrollView的滚动事件影响,也不会触发嵌套警告。
内容的提问来源于stack exchange,提问作者Material
相关产品推荐
相关产品推荐

