[React Native] VirtualizedLists should never be nested inside plain ScrollViews with the same orientation... 해결
🆘 😕 에러명
VirtualizedLists should never be nested inside plain ScrollViews with the same orientation
because it can break windowing and other functionality - use another VirtualizedList-backed container instead.
❓ 🧐 원인
ScrollView와 FlatList를 중첩 사용하여 발생
먼저 ScrollView와 FlatList에 대해 알아보고, 둘을 중첩 사용하면 안 되는 이유에 대해 설명드리겠습니다!
ScrollView와 FlatList란? 🧐
* ScrollView : 여러 구성 요소와 보기를 포함할 수 있는 일반 스크롤 컨테이너
* FlatList : 가장 편리한 기능을 지원하는 기본 플랫 목록을 렌더링 하기 위한 고성능 인터페이스
간단히 ScrollView와 FlatList의 장단점을 비교해보자면 다음과 같습니다. 🙂
ScrollView | FlatList | |
메모리 관리 | 메모리 관리 없음 | 자동 메모리 관리 |
렌더링 및 퍼포먼스 | 1. 모든 양 한번에 렌더링 => 프레임 드랍, 초기 렌더링 시간↑, 메모리 사용량↑ (성능 저하) 2. 적은 양의 데이터 렌더링하기 좋음 |
1. 필요한 데이터만 렌더링 => 메모리 사용량↓, 처리 시간↓ (성능 향상) 2. 많은 양의 데이터 렌더링하기 좋음 3. 적은 양의 데이터임에도 불구하고, scroll을 매우 빠르게 작동 => 프레임 드랍, 렌더링 시간 ↑ 4. 보여지지 않는 부분은 단순 unmount => 많은 garbage collection 야기 |
데이터의 양에 따라 ScrollView나 FlatList를 적절히 사용하면 됩니다!
그렇다면, 이러한 ScrollView와 FlatList를 왜 중첩해서 사용하면 안 될까요? 🙄
ScrollView는 데이터의 양에 따라 높이가 동적으로 변하는 특징을 갖고 있습니다.
ScrollView와 FlatList가 같은 방향으로 쓰인다고 가정할 때,
ScrollView의 자식 요소를 한 번에 렌더링 하는 특성 + FlatList의 필요한 데이터만 렌더링 하는 특성이 만나면
=> 기기의 현재 화면에서 필요한 데이터와 필요하지 않은 데이터를 동시에 불러오는 데이터 렌더링 중첩 상황이 발생합니다.
이렇게 되면 사실상 필요한 데이터만 렌더링 하는 FlatList의 특성이 무색해지죠. 😅 그래서 해당 error가 발생합니다.
* error가 발생해도 화면 구동이 가능하지만, 비효율적인 방법인 것 같다는 게 제 의견입니다. :)
추가로
FlatList에는 스크롤이 가장 밑에 도착했을 때 필요한 부분을 다시 로드하는 'onEndReached'라는 속성이 있습니다.
마찬가지로 ScrollView와 FlatList가 같은 방향으로 쓰인다고 가정할 때, ScrollView 내부에 FlatList가 존재하면 (FlatList의 부모가 ScrollView이면) onEndReached가 호출되지 않습니다.
📌 😋 해결
ScrollView와 FlatList의 중첩 사용을 피한다.
FlatList도 ScrollView처럼 스크롤이 가능하다는 특성을 이용하여 데이터를 ScrollView 대신에 FlatList의 ListHeaderComponent, ListFooterComponent 속성을 사용하여 렌더링 하는 것을 추천드립니다. :)
참고
https://reactnative.dev/docs/scrollview
https://mniyunsu.github.io/react-native-scrollview/
https://gorapaduck.tistory.com/entry/React-Native-ScrollView-vs-FlatList-vs-RecyclerListView