React-Native outro contêiner suportado por VirtualizedList

39

Após a atualização para o react-native 0.61, recebo muitos avisos assim:

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

Qual é o outro VirtualizedList-backed containerque devo usar e por que agora é aconselhável não usar dessa maneira?

David Schilling
fonte
3
Você realmente deve mostrar algum código
Variag 16/10/19

Respostas:

27

Se alguém ainda está procurando uma sugestão para o problema descrito por @Ponleu e @David Schilling aqui (sobre conteúdo que está acima do FlatList), essa é a abordagem que eu adotei:

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

Você pode ler mais sobre isso aqui: https://facebook.github.io/react-native/docs/flatlist#listheadercomponent

Espero que ajude alguém. :)

Afraz Hussain
fonte
11
Você sabe por que isso deve ser melhor do que a maneira como o aviso é produzido?
David Schilling
2
@DavidSchilling porque a maneira como você tentou resultados com 2 contêineres de rolagem: ScrollViewe FlatList- você terá um comportamento inconsistente de rolagem. A maneira apresentada nesta resposta resulta em apenas 1 contêiner de rolagem e no Cabeçalho / Rodapé você pode exibir qualquer visualização, por mais complexa que seja.
Variag
Estou usando o componente function e obtive o problema de re-renderização do ContentThatGoesAboveTheFlatList. Qualquer solução para esta
Ponleu
11
@Ponleu Você pode memorizar seu componente ContentThatGoesAboveTheFlatList usando o useMemogancho fornecido pelo React, para evitar novas renderizações. Mais informações aqui: reactjs.org/docs/hooks-reference.html#usememo Deixe-me se for útil. :)
Afraz Hussain
9

Caso isso ajude alguém, foi assim que corrigi o erro no meu caso.

Eu tinha um FlatListaninhado dentro de um 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>
    );
}

e me livrei disso ScrollViewusando o FlatListpara renderizar tudo o que eu precisava, o que acabou com o aviso:

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
fonte
4

Observando os exemplos nos documentos dos quais mudei o contêiner de:

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

para:

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

e todos esses avisos desapareceram.

Variag
fonte
6
E se eu processar o conteúdo acima por FlatListdentro ScrollViewe quiser que esse conteúdo seja rolável?
Ponleu
Não é uma boa experiência do usuário ter duas visualizações roláveis, uma ao lado da outra. Eu tentaria aninhar dessa forma: '<View> <ScrollView> <Content /> </ScrollView> <FlatList ... /> </View>' (não testado)
Variag
Tenho certeza de que o FlatList não criará outro pergaminho, a menos que o envolvamos em um contêiner com a altura especificada.
Ponleu
11
Eu tenho o mesmo problema que @Ponleu. Eu tenho um ScrollViewinterior de que algum conteúdo e, em seguida, um FlatListtambém dentro do ScrollView. E eu quero que a tela inteira role juntos.
David Schilling
2
Como resolver este problema no android ??
MD. IBRAHIM KHALIL TANIM 04/12/19
0

O aviso aparece porque, ScrollViewe FlatListcompartilha a mesma lógica, se FlatListexecutado dentro ScrollView, é duplicado

A propósito SafeAreaView, não funciona para mim, a única maneira de resolver é

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

O erro desaparece

Tuan Dat Tran
fonte
0

Eu tentei algumas maneiras de resolver isso, incluindo ListHeaderComponentor ListFooterComponent, mas tudo não se encaixava para mim.

o layout que eu queria alcançar era assim, e eu queria ser rolado uma vez.

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

Primeiro, quero agradecer a essa questão e comentários, que me deram várias idéias.

Eu estava pensando em ListHeaderComponentlugares acima da Flatlist, mas como Flatlista direção da minha coluna era coluna, o cabeçalho que eu queria colocar ficava à esquerda do Flatlist:(

Então eu tive que tentar VirtualizedList-backedalgo. Eu apenas tentei empacotar todos os componentes VirtualizedList, onde renderItemsdá o índice e lá eu poderia passar os componentes condicionalmente renderItems.

Eu poderia ter trabalhado nisso Flatlist, mas ainda não tentei.
Finalmente, fica assim.

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

e, claro, capaz de rolar a tela inteira.

Takahiro Nishino
fonte
-6

Esse problema ocorre quando você está usando o <FlatList />interior <ScrollView>com a mesma orientação.

Para corrigir isso, basta adicionar "horizontal" ao seu FlatList:

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

NB: O seu FlatList será renderizado horizontalmente

Brahim DEBBAGH
fonte
você entendeu mal a pergunta
Giorgi Gvimradze