React-Native inny kontener wspierany przez VirtualizedList

38

Po przejściu na natywną wersję 0.61 otrzymuję wiele takich ostrzeżeń:

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

Z czego jeszcze VirtualizedList-backed containerpowinienem korzystać i dlaczego nie zaleca się takiego używania?

David Schilling
źródło
3
Naprawdę powinieneś pokazać kod
Variag

Odpowiedzi:

27

Jeśli ktoś nadal szuka sugestii dotyczącej problemu opisanego tutaj przez @Ponleu i @Davida Schillinga (w odniesieniu do treści wykraczających poza FlatList), to takie podejście zastosowałem:

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

Możesz przeczytać więcej na ten temat tutaj: https://facebook.github.io/react-native/docs/flatlist#listheadercomponent

Mam nadzieję, że to komuś pomaga. :)

Afraz Hussain
źródło
1
Czy wiesz, dlaczego powinno to być lepsze niż sposób generowania ostrzeżenia?
David Schilling
2
@DavidSchilling, ponieważ sposób, w jaki próbowałeś wyników z 2 kontenerami przewijania: ScrollViewi FlatList- otrzymasz niespójne zachowanie przewijania. Sposób przedstawiony w tej odpowiedzi daje w wyniku tylko 1 pojemnik przewijania, aw nagłówku / stopce możesz umieścić dowolny widok, bez względu na to, jak skomplikowany.
Variag
Korzystam ze składnika funkcji i dostałem problem z ponownym renderowaniem ContentThatGoesAboveTheFlatList. Wszelkie rozwiązania w tym zakresie
Ponleu,
1
@Ponleu Możesz zapamiętać komponent ContentThatGoesAboveTheFlatList za pomocą useMemohaka dostarczonego przez React, aby uniknąć ponownego renderowania. Więcej informacji tutaj: reagjs.org/docs/hooks-reference.html#usememo Daj mi, jeśli to pomocne. :)
Afraz Hussain
8

Na wypadek, gdyby to komuś pomogło, tak naprawiłem błąd w moim przypadku.

Miałem FlatListgniazdo w 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>
    );
}

i pozbyłem się tego ScrollView, używając FlatListdo renderowania wszystkiego, czego potrzebowałem, co pozbyło się ostrzeżenia:

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}
        />
    );
}
Edward D'Souza
źródło
4

Patrząc na przykłady w dokumentach zmieniłem kontener z:

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

do:

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

i wszystkie te ostrzeżenia zniknęły.

Variag
źródło
6
Co zrobić, jeśli czynią treść powyższej FlatListwnętrzności ScrollViewi chcą, że zawartość być przewijane?
Ponleu,
Nie jest dobrym doświadczeniem użytkownika mieć dwa przewijalne widoki jeden obok drugiego. Próbowałbym zagnieździć to w następujący sposób: „<View> <ScrollView> <Content /> </ScrollView> <FlatList ... /> </View> '(nie testowano)
Variag
Jestem prawie pewien, że FlatList nie utworzy kolejnego zwoju, chyba że zawiniemy go w pojemnik o określonej wysokości.
Ponleu,
1
mam taki sam problem jak @Ponleu. Mam w ScrollViewśrodku trochę treści, a potem FlatListtakże wewnątrz ScrollView. I chcę, aby cały ekran przewijał się razem.
David Schilling,
2
Jak rozwiązać ten problem w Androidzie?
MD. IBRAHIM KHALIL TANIM
0

Ostrzeżenie pojawia się, ponieważ ScrollViewi FlatListma tę samą logikę, jeśli jest FlatListuruchomione w środku ScrollView, jest duplikowane

Nawiasem mówiąc SafeAreaView, nie działa dla mnie, jedynym sposobem na rozwiązanie jest

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

Błąd znika

Tuan Dat Tran
źródło
0

Wypróbowałem kilka sposobów rozwiązania tego problemu, w tym ListHeaderComponentlub ListFooterComponent, ale to wszystko nie pasowało do mnie.

układ, który chciałem osiągnąć, jest taki i chciałem raz przewinąć.

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

Najpierw chcę powiedzieć dzięki temu problemowi i komentarzom, które dały mi mnóstwo pomysłów.

Myślałem o ListHeaderComponentmiejscach nad płaską listą, ale ponieważ moim Flatlistkierunkiem była kolumna, nagłówek, który chciałem umieścić, znajdował się po lewej stronie Flatlist:(

Potem musiałem spróbować VirtualizedList-backed. Właśnie próbowałem spakować wszystkie komponenty VirtualizedList, gdzie renderItemsdaje indeks i tam mogłem warunkowo przekazać komponenty renderItems.

Mógłbym z tym pracować Flatlist, ale jeszcze nie próbowałem.
Wreszcie wygląda to tak.

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

i oczywiście w stanie przewijać cały ekran.

Takahiro Nishino
źródło
-6

Ten problem pojawia się, gdy używasz <FlatList />wnętrza <ScrollView>z tą samą orientacją.

Aby to naprawić, po prostu dodaj „poziomą” do swojej FlatList:

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

Uwaga: Twoja płaska lista będzie renderowana w poziomie

Brahim DEBBAGH
źródło
źle zrozumiałeś pytanie
Giorgi Gvimradze