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

  1. SDK Version: 36
  2. Platforms(Android/iOS/web/all): iOS (simulator)

I get this warning after upgrading to 35/36 from 34. I’m not really sure what to do with it. I have FlatLists within ScrollViews …but that’s what I need basically …anyone else came around this issue and solved it?

Best,
Andy

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

Stack trace:
node_modules/react-native/Libraries/YellowBox/YellowBox.js:71:8 in console.warn
node_modules/expo/build/environment/muteWarnings.fx.js:18:23 in warn
node_modules/react-native/Libraries/Lists/VirtualizedList.js:1054:16 in ScrollView.Context.Consumer.props.children
node_modules/react-native/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js:14701:25 in updateContextConsumer
node_modules/react-native/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js:20459:25 in beginWork$$1
node_modules/react-native/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js:19370:24 in performUnitOfWork
node_modules/react-native/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js:19347:39 in workLoopSync
node_modules/react-native/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js:18997:22 in renderRoot
[native code]:null in renderRoot
node_modules/react-native/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js:18709:28 in runRootCallback
[native code]:null in runRootCallback
node_modules/react-native/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js:5642:32 in runWithPriority$argument_1
node_modules/scheduler/cjs/scheduler.development.js:643:23 in unstable_runWithPriority
node_modules/react-native/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js:5638:22 in flushSyncCallbackQueueImpl
node_modules/react-native/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js:5627:28 in flushSyncCallbackQueue
node_modules/react-native/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js:18556:30 in scheduleUpdateOnFiber
node_modules/react-native/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js:7799:17 in classComponentUpdater.enqueueSetState
node_modules/react/cjs/react.development.js:325:31 in Component.prototype.setState
http://127.0.0.1:19001/node_modules/expo/AppEntry.bundle?platform=ios&dev=true&minify=false&hot=false:158526:34 in
node_modules/promise/setimmediate/core.js:37:14 in tryCallOne
node_modules/promise/setimmediate/core.js:123:25 in setImmediate$argument_0
node_modules/react-native/Libraries/Core/Timers/JSTimers.js:146:14 in _callTimer
node_modules/react-native/Libraries/Core/Timers/JSTimers.js:194:17 in _callImmediatesPass
node_modules/react-native/Libraries/Core/Timers/JSTimers.js:458:30 in callImmediates
[native code]:null in callImmediates
node_modules/react-native/Libraries/BatchedBridge/MessageQueue.js:407:6 in __callImmediates
node_modules/react-native/Libraries/BatchedBridge/MessageQueue.js:143:6 in __guard$argument_0
node_modules/react-native/Libraries/BatchedBridge/MessageQueue.js:384:10 in __guard
node_modules/react-native/Libraries/BatchedBridge/MessageQueue.js:142:17 in __guard$argument_0
[native code]:null in flushedQueue
[native code]:null in invokeCallbackAndReturnFlushedQueue

1 Like

I get the same warning after upgrading to 36.

My code looks like this:

<SafeAreaView style={{ flex: 1 }}>
    <ScrollView>
        <View>
            <Text>some header</Text>
        </View>

        <View>
            <FlatList/>
        </View>

        <View>
            <Text>another header for a second list</Text>
        </View>

        <View>
            <FlatList/>
        </View>
    </ScrollView>
</SafeAreaView>
1 Like

I don’t get an error though, just a warning.

Yes sorry, warning you are right.

1 Like

You will need to remove ScrollView and use only SafeAreaView. If you have a header or footer try putting it inside your flatlist in ListHeaderComponent and ListFooterComponent. I have had good luck with this but run into problems when I have more than one flatlist with headers on a screen. But the key is to use only SafeAreaView and mess with putting your code inside Views and header and footer components.

But this seems like a bug …hopefully a temporary bug?

I found someone sugesting just removing the warnings until it has been fixed. But I’m not sure if that is a good idea:

import { YellowBox } from 'react-native'

YellowBox.ignoreWarnings([
	'VirtualizedLists should never be nested', // TODO: Remove when fixed
])
1 Like

<SafeAreaView> only works on iOS version 11 or later

I believe it acts as a plain view in android and such. This came with the upgrade to Expo SDK 36 and it’s newer versions of react native. Expo updated their docs to reflect the correct flat list usage inside a SafeAreaView. Using both creates two scroll environments.

This is not a bug. FlatLists inside of ScrollViews with the same direction (a horizontal FlatList inside a vertical ScrollView is not an issue) will render all of the items at once and can’t be virtualized. So you can have a FlatList inside a ScrollView but all the performance benefits will be worthless as they’re not working.

It was like that before SDK 36, but now they added a warning. As long as your FlatList isn’t big and you don’t render a lot of items you can hide the warning or just ignore it.

2 Likes

@hirbod how do you define horizontal and vertical for those? I think I didn’t define that.

And I only tried shortly and when I put the FlatList inside SafeAreaView, only the content of the FlatList where scrolling.

FlatList and ScrollView have a simple prop for that

<FlatList horizontal>
<ScrollView horizontal>

But you should only set this if you actually have a horizontal one. Vertical is by default so you don’t have to set it.

Setting horizontal will change the scroll direction from vertical to horizontal though (this one is useful if you use multiple react-native-snap-carousel for example, where you have a vertical ScrollView and multiple (or single) horizontal FlatLists)

2 Likes

So FlatLists inside ScollViews are fine when you want everything to render immediately?

And when you want virtualization (lazy-load) you should use SafeAreaView?

This is actually pretty useful information …and more or less what I thought. But then the warnings should not be there!?

This is not a bug. FlatLists inside of ScrollViews with the same direction (a horizontal FlatList inside a vertical ScrollView is not an issue) will render all of the items at once and can’t be virtualized. So you can have a FlatList inside a ScrollView but all the performance benefits will be worthless as they’re not working.

Good to know. Thanks, @hirbod.