错误 - VirtualizedLists 不应嵌套在具有相同方向的普通 ScrollViews 中

Ale*_*ghi 8 react-native

我正在开发一个react-native应用程序,我必须在Scrollview 中放置一个对象列表,所以我使用FlatList组件来完成它。这是生成错误的代码段:

<ScrollView contentContainerStyle={style}>
   Other components
   <FlatList
       style={style}
       data={data}
       scrollEnabled={false}
       keyExtractor={(item, index) => index.toString()}
       renderItem={({ item, index}) => (somethings)}
   />
   Other components
</ScrollView>
Run Code Online (Sandbox Code Playgroud)

完整的错误是:VirtualizedLists 不应该嵌套在具有相同方向的普通 ScrollViews 中,因为它会破坏窗口和其他功能 - 改用另一个 VirtualizedList 支持的容器。

Jit*_*har 41

避免使用具有相同方向的 FlatList。相反,像这样重构你的代码——

  <ScrollView contentContainerStyle={style}>
    Other components
    {
      data.map((item)=> <Somthing item={item}/>)
    }
    Other components
  </ScrollView>
Run Code Online (Sandbox Code Playgroud)

  • 如果您要渲染的列表非常小,那么这个答案是可以的,但较大的列表会给您带来性能和内存问题 (26认同)

小智 27

解决方案: 我也遇到了同样的问题FlatList。然后下面的包解决了我的问题。

'反应本机虚拟化视图'

import { ScrollView } from 'react-native-virtualized-view'
Run Code Online (Sandbox Code Playgroud)


小智 26

Flatlist 有自己的 ScrollView,您可以使用它滚动列表,因此无需将 Flatlist 放入 ScrollView,这就是它发出警告的原因,两个滚动视图都会发生冲突,其中一个(主要是父滚动视图)可以工作。

  • 代码没有预见到这一点,我需要一个可滚动的外部结构,并且位于其他组件内部,包括我用带有scrollEnabled = {false}的FlatList表示的对象列表 (9认同)

rul*_*bir 22

该错误是不言自明的,即使只是误报,避免此类事件也应该符合开发人员的最大利益。您的具体情况可以使用以下解决方案:

<FlatList
  data={data}
  keyExtractor={(item, index) => `key-${index}`}
  ListHeaderComponent={() => (
    <SomeComponents>
      ...Some components those need to be on top of the list
    </SomeComponents>
  )}
  ListFooterComponent={() => (
    <SomeComponents>
      ...Some components those need to be below the list
    </SomeComponents>
  )}
  renderItem={({ item, index}) => (somethings)}
/>
Run Code Online (Sandbox Code Playgroud)

另请注意,如果您需要更复杂的列表,需要列表本身的页眉和页脚,您可以尝试SectionList.


小智 21

您的组件FlatList具有ScrollView相同的方向(垂直),因此您需要将组件放在ScrollView水平方向内,如下所示:

<View>
    <ScrollView nestedScrollEnabled={true} style={{ width: "100%" }} >
    <View>
    <ScrollView horizontal={true} style={{ width: "100%" }}>
        <FlatList />
    </ScrollView>
    </View>
    </ScrollView>
</View>
Run Code Online (Sandbox Code Playgroud)

  • 这将消除错误,但如果两个列表的所需方向都是垂直的,那么它可能不是一个好的解决方案 - 因此它更像是一种反模式而不是正确的解决方案 (9认同)

Muh*_*san 15

解决方案 1:使用FlatListpropsListHeaderComponent并在其中创建所有页面顶部部分。像这样的东西:在此输入图像描述

这不会显示任何警告或错误。

解决方案 2: 因为只有父视图才会滚动 ( ScrollView) 而子视图不会滚动FlatList,因此要消除警告,您可以将属性scrollEnabled={false}传递给FlatList.

如果没有成功,则从react-native导入LogBox并将其写入您的组件中

useEffect(() => {
  LogBox.ignoreLogs(["VirtualizedLists should never be nested"])
}, [])
Run Code Online (Sandbox Code Playgroud)

希望该警告将被删除。

  • 这并没有解决问题,而只是抑制错误消息。这个消息的出现是有原因的,你应该尝试解决它而不是压抑它。 (2认同)

Rob*_*bin 11

任何想要解决此问题的人都可以使用VirtualizedScrollView如下自定义:

import React from 'react';
import { FlatList } from 'react-native';

const VirtualizedScrollView = props => {
  return (
    <FlatList
      {...props}
      data={[]}
      keyExtractor={(e, i) => 'dom' + i.toString()}
      ListEmptyComponent={null}
      renderItem={null}
      ListHeaderComponent={() => (
        <>{props.children}</>
      )}
    />
  );
};

export default VirtualizedScrollView;
Run Code Online (Sandbox Code Playgroud)

然后,如果您使用FlatListinside VirtualizedScrollView,它将不会收到警告/错误。

<VirtualizedScrollView>
  <FlatList 
    /*--- your props ---*/
  />
</VirtualizedScrollView>
Run Code Online (Sandbox Code Playgroud)

有一个 npm 包,我可以在其中获取此代码,您也可以使用这个


小智 8

如果您需要将 FlatList 展开到滚动视图中,则需要从 FlatList 禁用滚动并使用 展开它flex: 1。要禁用滚动,请冷添加以下代码

<FlatList
nestedScrollEnabled={true}
scrollEnabled={false}
data={[1,2,3,4]}
renderItem={({item}) => {
    return <CardItemPurchasedList/>
}}
Run Code Online (Sandbox Code Playgroud)


Dar*_*iya 6

当为 false 时,视图无法通过触摸交互滚动。

<ScrollView>
    <ListView 
        scrollEnabled={false} />
</ScrollView>
Run Code Online (Sandbox Code Playgroud)

我通过scrollEnabled={false}在内部设置解决了这个问题VirtualizedLists,因为它不会使其通过触摸交互滚动。默认情况下,它有scrollEnabled={true},这会导致两个方向相同的可滚动列表。但如果它们有两个不同的方向,那就没有问题了!


小智 0

您可以通过使用相同的平面列表并在切换时切换数据来解决两个垂直的问题(我假设它们并排,用分段控件分开?)。如果它们只是两个相继的垂直平面列表,请使用SectionList。

对于水平的,您可以尝试将水平 FlatList 放入垂直 FlatList 的 ListHeaderComponent 中,看看会发生什么。如果您在垂直滚动视图中使用垂直 FlatList,则可能会很卡顿,但也许使用两个不同的轴可能没问题。另一个选项是两个仅在水平滚动视图中显示一些项目并具有“显示更多”。

最后一个选项是重新设计/重新思考页面,因此它没有做太多事情。在移动设备上,少即是多,开发人员/设计师喜欢将桌面思维移植到移动设备上。可能值得一试。