Search code examples
react-nativeexposcrollview

React Native - VirtualizedLists should never be nested inside plain ScrollViews with the same orientation


I'm working on an app for existing web application with expo cli.

I have completed the home screen but I'm getting this warning when using ScrollView

VirtualizedLists should never be nested inside plain ScrollViews with the same orientation - use another VirtualizedList-backed container instead.

I have a folder screens where I've all the pages of the website. so currently I have Home.js where I have different sections.

<View>
  <Showcase />
  <StepsList />
  <HomeInfo />
  <HomeCorporateMenu />
  <HomeMonthlyMenus />
</View>

Then rendeing this component in the root component App.js. but I was not able to scroll down to see other sections.

So I've added SafeAreaView and ScrollView components. now I'm able to scroll but sometimes I get that warning in the console.

I have looked it up SO and found some solutions.

Added style={{ flex: 1 }} and keyboardShouldPersistTaps='always' to ScrollView component

But Still getting the same warning. Any suggestions?

<SafeAreaView style={styles.container}>
  <ScrollView>
    <Header />
    <HomeScreen />
  </ScrollView>
</SafeAreaView>

Solution

  • The warning is, obviously, telling you that you shouldn't nest multiple VirtualizedList (FlatList and SectionList) components with the same orientation (the orientation of your lists is probably vertical).

    To do it properly, and for the warning to disappear, you have to use the ListHeaderComponent or ListFooterComponent prop of the VirtualizedList and nest them like this:

    const App = () => {
      const ListFooterComponent = (
        <>
          <FlatList
            // other FlatList props
            data={stepsListData}
          />
          <FlatList
            // other FlatList props
            data={homeInfoData}
          />
          <FlatList
            // other FlatList props
            data={homeCorporateMenuData}
          />
          {/* ... */}
        </>
      );
    
      return (
        <FlatList
          // other FlatList props
          data={showcaseData}
          ListFooterComponent={ListFooterComponent}
        />
      );
    };
    

    Or another possible workaround (and not an official resolution) would be to use a FlatList with empty data and renderItem props instead of using a ScrollView. Instead of this:

    const App = () => {
      return (
        <SafeAreaView style={styles.container}>
          <ScrollView>
            <Header />
            <HomeScreen />
          </ScrollView>
        </SafeAreaView>
      );
    };
    

    You can use this:

    const emptyData = [];
    
    const renderNullItem = () => null;
    
    const App = () => {
      const ListFooterComponent = (
        <>
          <Header />
          <HomeScreen />
        </>
      );
    
      return (
        <SafeAreaView style={styles.container}>
          <FlatList
            data={emptyData}
            renderItem={renderNullItem}
            ListFooterComponent={ListFooterComponent}
          />
        </SafeAreaView>
      );
    };