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í?


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. :)


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}
        />
    );
}

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.


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


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.


-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


Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.