React-Native otro contenedor respaldado por VirtualizedList

39

Después de actualizar a react-native 0.61, recibo muchas advertencias como esta:

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

¿Cuál es el otro VirtualizedList-backed containerque debo usar, y por qué ahora se recomienda no usar así?

David Schilling
fuente
3
Realmente deberías mostrar algún código
Variag

Respuestas:

27

Si alguien todavía está buscando una sugerencia sobre el problema que @Ponleu y @David Schilling han descrito aquí (con respecto al contenido que va por encima de la lista plana), entonces este es el enfoque que tomé:

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

Puede leer más sobre esto aquí: https://facebook.github.io/react-native/docs/flatlist#listheadercomponent

Esperemos que ayude a alguien. :)

Afraz Hussain
fuente
1
¿Sabes por qué esto debería ser mejor que la forma en que se produce la advertencia?
David Schilling
2
@DavidSchilling porque la forma en que probó resultados con 2 contenedores de desplazamiento: ScrollViewy FlatList- obtendrá un comportamiento de desplazamiento inconsistente. La forma presentada en esta respuesta da como resultado solo 1 contenedor de desplazamiento y en Encabezado / Pie de página puede poner cualquier vista, sin importar cuán compleja sea.
Variag
Estoy usando el componente de función y obtuve el problema Content-ThatGoesAboveTheFlatList re-render. Cualquier solución sobre esto
Ponleu
1
@Ponleu Puede memorizar su componente ContentThatGoesAboveTheFlatList utilizando el useMemogancho provisto por React, para evitar re-renderizaciones. Más información aquí: reactjs.org/docs/hooks-reference.html#usememo Déjame si es útil. :)
Afraz Hussain
9

En caso de que esto ayude a alguien, así es como solucioné el error en mi caso.

Tenía un FlatListanidado dentro de 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>
    );
}

y me deshice del ScrollViewuso de FlatListpara renderizar todo lo que necesitaba, lo que eliminó la advertencia:

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

Mirando los ejemplos en documentos he cambiado el contenedor de:

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

a:

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

y todas esas advertencias desaparecieron.

Variag
fuente
66
¿Qué sucede si presento contenido en el FlatListinterior ScrollViewy quiero que ese contenido sea desplazable?
Ponleu
No es una buena experiencia para el usuario tener dos vistas desplazables una al lado de la otra. Intentaría anidarlo así: '<View> <ScrollView> <Content /> </ScrollView> <FlatList ... /> </View>' (no probado)
Variag
Estoy bastante seguro de que FlatList no creará otro desplazamiento, a menos que lo envuelvamos en un contenedor con una altura especificada.
Ponleu
1
Tengo el mismo problema que @Ponleu. Tengo ScrollViewdentro de ese contenido y luego FlatListtambién dentro ScrollView. Y quiero que toda la pantalla se desplace juntos.
David Schilling
2
¿Cómo resolver este problema en Android?
MD. IBRAHIM KHALIL TANIM
0

La advertencia aparece porque ScrollViewy FlatListcomparte la misma lógica, si se FlatListejecuta dentro ScrollView, está duplicada

Por cierto SafeAreaViewno funciona para mí, la única forma de resolver es

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

El error desaparece

Tuan Dat Tran
fuente
0

Intenté algunas formas de resolver esto, incluyendo ListHeaderComponento ListFooterComponent, pero no me quedó bien.

El diseño que quería lograr es así, y quería que me desplazaran una vez.

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

Primero quiero agradecer este problema y comentarios, que me dieron muchas ideas.

Estaba pensando en ListHeaderComponentlugares sobre la lista plana, pero como Flatlistla dirección de mi era la columna, el encabezado que quería colocar estaba a la izquierda de Flatlist:(

Luego tuve que probarme VirtualizedList-backedalgo. Solo intenté empaquetar todos los componentes VirtualizedList, donde renderItemsda índice y allí podría pasar componentes condicionalmente renderItems.

Podría haber trabajado con esto Flatlist, pero aún no lo he intentado.
Finalmente se ve así.

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

y, por supuesto, capaz de desplazar toda la pantalla.

Takahiro Nishino
fuente
-6

Este problema viene cuando está usando <FlatList />adentro <ScrollView>con la misma orientación.

Para solucionar esto, simplemente agregue "horizontal" a su FlatList:

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

NB: su FlatList se representará horizontalmente

Brahim DEBBAGH
fuente
entendiste