React-Native un autre conteneur soutenu par VirtualizedList


39

Après la mise à niveau vers la version 0.61 native de React, je reçois de nombreux avertissements comme celui-ci:

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

Quel est l'autre VirtualizedList-backed containerque je devrais utiliser, et pourquoi est-il maintenant conseillé de ne pas utiliser comme ça?


3
Vous devriez vraiment montrer du code
Variag

Réponses:


27

Si quelqu'un cherche toujours une suggestion au problème que @Ponleu et @David Schilling ont décrit ici (concernant le contenu qui va au-dessus de la FlatList), alors c'est l'approche que j'ai adoptée:

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

Vous pouvez en savoir plus à ce sujet ici: https://facebook.github.io/react-native/docs/flatlist#listheadercomponent

J'espère que cela aide quelqu'un. :)


1
Savez-vous pourquoi cela devrait être meilleur que la façon dont l'avertissement est produit?
David Schilling

2
@DavidSchilling parce que la façon dont vous avez essayé les résultats avec 2 conteneurs de défilement: ScrollViewet FlatList- vous obtiendrez un comportement de défilement incohérent. La manière présentée dans cette réponse se traduit par un seul conteneur de défilement et dans En-tête / Pied de page, vous pouvez mettre n'importe quelle vue, quelle que soit sa complexité.
Variag

J'utilise un composant de fonction et j'ai eu un problème de nouveau rendu ContentThatGoesAboveTheFlatList. Toute solution à ce sujet
Ponleu

1
@Ponleu Vous pouvez mémoriser votre composant ContentThatGoesAboveTheFlatList en utilisant le useMemohook fourni par React, pour éviter les re-rendus. Plus d'informations ici: reactjs.org/docs/hooks-reference.html#usememo Laissez-moi si cela est utile. :)
Afraz Hussain

9

Juste au cas où cela aiderait quelqu'un, c'est ainsi que j'ai corrigé l'erreur dans mon cas.

J'avais un FlatListniché à l'intérieur d'un 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>
    );
}

et je me suis débarrassé de ScrollViewen utilisant le FlatListpour rendre tout ce dont j'avais besoin, ce qui s'est débarrassé de l'avertissement:

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

En regardant les exemples dans les documents, j'ai changé de conteneur depuis:

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

à:

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

et tous ces avertissements ont disparu.


6
Que se passe-t-il si je rend le contenu ci-dessus à l' FlatListintérieur ScrollViewet que je souhaite que ce contenu puisse défiler?
Ponleu

Ce n'est pas une bonne expérience utilisateur d'avoir deux vues déroulantes l'une à côté de l'autre. J'essaierais de l'imbriquer comme ceci: '<View> <ScrollView> <Content /> </ScrollView> <FlatList ... /> </View>' (non testé)
Variag

Je suis sûr que FlatList ne créera pas un autre parchemin, à moins que nous ne l'enveloppions dans un conteneur de hauteur spécifiée.
Ponleu

1
j'ai le même problème que @Ponleu. J'ai un ScrollViewcontenu à l'intérieur de ce contenu, puis un contenu FlatListà l'intérieur du ScrollView. Et je veux que tout l'écran défile ensemble.
David Schilling

2
Comment résoudre ce problème dans Android ??
MD. IBRAHIM KHALIL TANIM


0

L'avertissement apparaît car ScrollViewet FlatListpartage la même logique, siFlatList exécuté à l'intérieur ScrollView, il est dupliqué

Au fait SafeAreaView cela ne fonctionne pas pour moi, la seule façon de résoudre est

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

L'erreur disparaît


0

J'ai essayé quelques façons de résoudre ce problème, y compris ListHeaderComponentouListFooterComponent , mais tout ne me convenait pas.

la disposition que je voulais réaliser est comme ça, et je voulais faire défiler une fois.

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

Je veux d'abord dire merci à ce numéro et à ces commentaires, qui m'ont donné beaucoup d'idées.

Je pensais à des ListHeaderComponentendroits au-dessus de la Flatlist, mais comme ma Flatlistdirection était la colonne, l'en-tête que je voulais placer était à gauche de la Flatlist:(

Ensuite, j'ai dû essayer VirtualizedList-backedquelque chose. J'ai juste essayé d'emballer tous les composants VirtualizedList, où renderItemsdonne l'index et où je pouvais passer des composants sous condition renderItems.

J'aurais pu travailler avec Flatlist, mais je n'ai pas encore essayé.
Enfin, cela ressemble à ceci.

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

et bien sûr capable de faire défiler tout l'écran.


-6

Ce problème survient lorsque vous utilisez l' <FlatList />intérieur<ScrollView> avec la même orientation.

Pour résoudre ce problème, ajoutez simplement "horizontal" à votre FlatList:

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

NB: Votre FlatList sera rendu horizontalement


vous avez mal compris la question
Giorgi Gvimradze
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.