React-Native другой контейнер, поддерживаемый VirtualizedList

39

После обновления до версии 0,61, я получил много предупреждений:

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

Что еще VirtualizedList-backed containerя должен использовать, и почему теперь не рекомендуется так использовать?

Дэвид Шиллинг
источник
3
Вы должны действительно показать код
Варяг

Ответы:

27

Если кто-то все еще ищет предложение по проблеме, которую @Ponleu и @David Schilling описали здесь (относительно контента, который выходит за пределы FlatList), то я выбрал такой подход:

<SafeAreaView style={{flex: 1}}>
    <FlatList
      data={data}
      ListHeaderComponent={ContentThatGoesAboveTheFlatList}
      ListFooterComponent={ContentThatGoesBelowTheFlatList} />
</SafeAreaView>

Вы можете прочитать больше об этом здесь: https://facebook.github.io/react-native/docs/flatlist#listheadercomponent

Надеюсь, это кому-нибудь поможет. :)

Афраз Хуссейн
источник
1
Знаете ли вы, почему это должно быть лучше, чем при получении предупреждения?
Дэвид Шиллинг
2
@DavidSchilling, потому что, как вы опробовали результаты с 2 контейнерами прокрутки: ScrollViewи FlatList- вы получите непоследовательное поведение прокрутки. Способ, представленный в этом ответе, приводит только к одному контейнеру прокрутки, а в верхнем / нижнем колонтитуле вы можете поместить любое представление, независимо от того, насколько оно сложное.
Варяг
Я использую компонент функции, и получил ContentThatGoesAboveTheFlatList проблема повторного рендеринга. Любое решение по этому
вопросу
1
@Ponleu Вы можете запоминать свой компонент ContentThatGoesAboveTheFlatList, используя useMemoхук, предоставленный React, чтобы избежать повторного рендеринга. Более подробная информация здесь: reactjs.org/docs/hooks-reference.html#usememo Позвольте мне, если это будет полезно. :)
Афраз Хуссейн
9

На всякий случай, если это кому-то поможет, я исправил ошибку в моем случае.

У меня было FlatListвложенное внутри ScrollView:

render() {
    return (
        <ScrollView>
            <h1>{'My Title'}</h1>
            <FlatList
                data={this.state.myData}
                renderItem={({ item }) => {
                    return <p>{item.name}</p>;
                }}
            />
            {this.state.loading && <h2>{'Loading...'}</h2>}
        </ScrollView>
    );
}

и я избавился от ScrollViewс помощью, FlatListчтобы сделать все, что мне нужно, что избавилось от предупреждения:

render() {
    const getHeader = () => {
        return <h1>{'My Title'}</h1>;
    };

    const getFooter = () => {
        if (this.state.loading) {
            return null;
        }
        return <h2>{'Loading...'}</h2>;
    };

    return (
        <FlatList
            data={this.state.myData}
            renderItem={({ item }) => {
                return <p>{item.name}</p>;
            }}
            ListHeaderComponent={getHeader}
            ListFooterComponent={getFooter}
        />
    );
}
Эдвард д'Суза
источник
4

Глядя на примеры в документах, я изменил контейнер с:

<ScrollView>
    <FlatList ... />
</ScrollView>

чтобы:

<SafeAreaView style={{flex: 1}}>
    <FlatList ... />
</SafeAreaView>

и все эти предупреждения исчезли.

Варяг
источник
6
Что делать, если я рендерим содержимое выше FlatListвнутренней части ScrollViewи хочу, чтобы этот контент можно было прокручивать?
Ponleu
Не очень удобно иметь два прокручиваемых представления друг за другом. Я хотел бы попробовать гнездиться это так: '<View> <ScrollView> <Содержание /> </ ScrollView> <FlatList ... /> </ View>' (не проверено)
Варяг
Я почти уверен, что FlatList не создаст другую прокрутку, если мы не завернем его в контейнер с заданной высотой.
Понле
1
У меня та же проблема, что и у @Ponleu. У меня есть что-то ScrollViewвнутри, а затем FlatListи внутри ScrollView. И я хочу, чтобы весь экран прокручивался вместе.
Дэвид Шиллинг
2
Как решить эту проблему в Android?
доктор медицинских наук ИБРАХИМ ХАЛИЛ ТАНИМ
0

На мой взгляд, я могу использовать карту вместо FlatList. Но в моем случае я не хочу показывать большой список. Неиспользование FlatList может вызвать проблемы с производительностью. поэтому я использовал это для подавления предупреждения https://github.com/GeekyAnts/NativeBase/issues/2947#issuecomment-549210509

tvankith
источник
0

Появляется предупреждение, потому что ScrollViewи FlatListиспользуют ту же логику, если FlatListзапустить внутри ScrollView, оно дублируется

Кстати SafeAreaView, не работает для меня, единственный способ решить

<ScrollView>
    {data.map((item, index) => {
        ...your code
    }}
</ScrollView>

Ошибка исчезает

Туан Дат Чан
источник
0

Я попробовал несколько способов решить эту проблему, включая ListHeaderComponentили ListFooterComponent, но все это мне не подходило.

макет, который я хотел достичь, похож на это, и я хотел получить прокрутку в один раз.

<ScrollView>
  <View>I'm the first view</View>
  <View>I'm the second view</View>
  <MyFlatList />
</ScrollView>

Сначала я хочу сказать спасибо этой проблеме и комментариям, которые дали мне кучу идей.

Я думал о ListHeaderComponentместах выше Flatlist, но так как мое Flatlistнаправление было столбцом, заголовок, который я хотел разместить, был слева от Flatlist:(

Тогда мне пришлось примерить VirtualizedList-backedвещь. Я просто попытался упаковать все компоненты VirtualizedList, где renderItemsдает индекс, и там я могу условно передать компоненты renderItems.

Я мог бы работать с этим Flatlist, но я еще не пробовал.
Наконец-то это выглядит так.

<View>
  <Virtualizedlist
    data={[]}
    initialNumToRender={1}
    renderItem={(props)=>{
      props.index===0 ? (1st view here) : props.index===1 ? (2nd view here) : (my flatlist)
    }}
    keyExtractor={item => item.key}
    getItemCount={2}
    getItem={ (data, index) => {
      return {
        id: Math.random().toString(12).substring(0),
      }
    }}
  />
</View>

(inside which lazyly renders↓)
  <View>I'm the first view</View>
  <View>I'm the second view</View>
  <MyFlatList />  

и, конечно, в состоянии прокрутить весь экран.

Такахиро Нишино
источник
-6

Эта проблема возникает, когда вы используете <FlatList />внутри <ScrollView>с той же ориентацией.

Чтобы это исправить, просто добавьте «горизонтальный» в свой FlatList:

<ScrollView>
    <FlatList **horizontal** ... />
</ScrollView>

NB. Ваш FlatList будет отображаться горизонтально

Брахим ДЭББАГ
источник
Вы неправильно поняли вопрос
Гиорги Гвимрадзе