【问题标题】:ERROR - VirtualizedLists should never be nested inside plain ScrollViews with the same orientation错误 - VirtualizedLists 不应该嵌套在具有相同方向的普通 ScrollViews 中
【发布时间】:2021-05-20 15:55:33
【问题描述】:

我正在开发一个 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>

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

【问题讨论】:

  • 有时它会禁用触摸,这不是很重要的警告
  • 您可以禁用此警告,它不会停用触摸,您不会在生产中遇到这种情况。
  • 禁用警告不是解决办法
  • 这篇文章说明了为什么会发生这种情况以及如何解决它:nyxo.app/…
  • @Tebo 你附加的文章无效

标签: react-native


【解决方案1】:

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

【讨论】:

  • 代码没有预见到这一点,我需要一个可滚动的外部结构和其他组件内部,包括我用带有 scrollEnabled={false} 的 FlatList 表示的对象列表
【解决方案2】:

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

<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)}
/>

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

【讨论】:

    【解决方案3】:

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

      <ScrollView contentContainerStyle={style}>
        Other components
        {
          data.map((item)=> <Somthing item={item}/>)
        }
        Other components
      </ScrollView>
    

    【讨论】:

    • 我认为这应该是公认的答案。这是最简单的。
    【解决方案4】:

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

    <View>
        <ScrollView nestedScrollEnabled={true} style={{ width: "100%" }} >
        <View>
        <ScrollView horizontal={true} style={{ width: "100%" }}>
            <FlatList />
        </ScrollView>
        </View>
        </ScrollView>
    </View>
    

    【讨论】:

      【解决方案5】:

      因为,只有父视图会滚动 (ScrollView) 而不是子 FlatList,所以要获得警告,您可以将 prop scrollEnabled={false} 传递给 FlatList。

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

      useEffect(() => {
        LogBox.ignoreLogs(["VirtualizedLists should never be nested"])
      }, [])
      

      希望警告将被删除。

      【讨论】:

      • 还是有错误
      • 我已经更新了我的评论,请立即尝试@Jim
      • 这并不能解决问题,而只是抑制错误消息。消息的出现是有原因的,您应该尝试解决它而不是压制它。
      • @Stophface 这不是问题,这只是一个警告,也许在下一个版本的 react-native 中,他们添加了检查子 FlatList 是否具有 scrollEnabled={false} 的道具然后不要'不显示警告。
      • 这是一个错误,而不是警告。抑制它时可能会产生副作用(它们在错误消息中提到)。
      【解决方案6】:

      任何想解决这个问题的人都可以使用自定义的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;
      

      那么如果你在VirtualizedScrollView里面使用FlatList,它就不会得到警告/错误。

      <VirtualizedScrollView>
        <FlatList 
          /*--- your props ---*/
        />
      </VirtualizedScrollView>
      

      有一个 npm 包,我得到这个代码,你也可以使用这个package

      【讨论】:

        【解决方案7】:

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

        对于水平的,您可以尝试将 Horizo​​ntal FlatList 放在垂直 FlatList 的 ListHeaderComponent 中,看看会发生什么。如果您在垂直滚动视图中使用垂直 FlatList 可能会很麻烦,但可能有两个不同的轴可能没问题。另一个选项是两个只在水平滚动视图中显示几个项目并有一个“显示更多”。

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

        【讨论】:

          【解决方案8】:

          我使用SectionList 方法解决了这个问题并想发布一个代码示例,因为我找到了Section data required by React Native to be clear but also quite prescriptive

           renderList = ({empty, posts}: {empty: boolean, posts: Array<Object>}) => (
              <SectionList
                sections={[
                  {type: 'MAP', data: [{}]}, // Static sections.
                  {type: 'PROFILE', data: [{}]},
                  {type: 'POSTS', data: posts} // Dynamic section data replaces the FlatList.
                ]}
                keyExtractor={(item, index) => index}
                renderItem={({item, section}) => {
                  switch (section.type) {
                    // Different components for each section type.
                    case 'MAP':
                      return <MapView />;
                    case 'PROFILE':
                      return <Profile />;
                    case 'POSTS':
                      return <Post item={item} />;
                    default:
                      return null;
                  }
                }}
                ItemSeparatorComponent={() => <Separator />}
                ListFooterComponent={() => <>{empty && <EmptyList />}</>}
              />
            );
          

          好在内容在逻辑上感觉非常独立,因此您可以轻松添加部分或拥有不同的动态数据源。

          (如果您正在构建一个表单并想要更好的键盘处理,您也可以尝试使用react-native-keyboard-aware-scroll-view 中的KeyboardAwareSectionList。)

          【讨论】:

            【解决方案9】:

            Flatlist 本身有一个集成的滚动视图,因此您可以通过移除 ScrollView 组件来解决此错误,而只保留 Fatlist 组件

            【讨论】:

            • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
            【解决方案10】:

            错误?您正在尝试在滚动视图组件中呈现 FlatList 组件,这就是引发警告的原因。

            解决方案使用 Flatlist 的 ListHeaderComponent={} 属性渲染组件,即在你的 flatlist 中添加如下属性

            const FlatList_Header = () => {
                return (
                    <View style={{
                        height: 45,
                        width: "100%",
                        backgroundColor: "#00B8D4",
                        justifyContent: 'center',
                        alignItems: 'center'
                                }}
                    >
             
                    <Text style={{ fontSize: 24, color: 'white' }}> Sample FlatList Header </Text>
             
                    </View>
                );
              }
            <FlatList
                data={BirdsName}
                renderItem={({ item }) => <ItemRender name={item.name} />}
                keyExtractor={item => item.id}
                ItemSeparatorComponent={ItemDivider}
                **ListHeaderComponent={FlatList_Header}**
                ListHeaderComponentStyle={{ borderBottomColor: 'red', borderBottomWidth: 2 }}
                  />
            

            请注意上面代码中 ListHeaderComponent 的使用,这应该会抑制警告。

            【讨论】:

              【解决方案11】:

              使用flatList,如this.ListHeaderComponentListFooterComponent

              <FlatList ListHeaderComponent={
                  <ScrollView
                      style={styles.yourstyle}
                      showsVerticalScrollIndicator={false}
                  >
                      <View style={styles.yourstyle}>
                      </View>
                  </ScrollView>
                  }
                  data={this.state.images}
                  renderItem={({ item, index }) => {
                      return (
                          <View
                              style={styles.yourstyle}
                          >
                              <Image
                                  source={{
                                      uri: item,
                                  }}
                                  style={styles.yourstyle}
                                  resizeMode={"contain"}
                              />
                              <Text
                                  numberOfLines={2}
                                  ellipsizeMode="tail"
                                  style={styles.yourstyle}
                              >
                                  {item.name}
                              </Text>
                          </View>
                      );
                  }}
                  keyExtractor={({ name }, index) => index.toString()}
                  ListFooterComponent={
                      <View style={styles.yourstyle}></View>
                  }
              />
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2021-10-25
                • 1970-01-01
                • 2022-12-07
                • 2020-03-24
                • 1970-01-01
                • 2020-05-29
                • 2021-11-21
                相关资源
                最近更新 更多