React-Native另一个由VirtualizedList支持的容器


38

升级到react-native 0.61之后,我收到很多类似的警告:

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

VirtualizedList-backed container我应该使用其他什么?为什么现在不建议那样使用?


3
您应该真正显示一些代码
Variag

Answers:


27

如果有人仍在寻找有关@Ponleu和@David Schilling在此处描述的问题的建议(关于FlatList上方的内容),那么这就是我采取的方法:

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

您可以在此处了解更多信息: https //facebook.github.io/react-native/docs/flatlist#listheadercomponent

希望它可以帮助某人。:)


1
您知道为什么这比发出警告的方式更好吗?
David Schilling

2
@DavidSchilling因为你的方式试图与2个滚动容器的结果:ScrollViewFlatList-你会得到不一致的滚动行为。此答案中显示的方式仅导致一个滚动容器,并且在页眉/页脚中可以放置任何视图,无论多么复杂。
Variag

我正在使用功能组件,并遇到ContentThatGoesAboveTheFlatList重新呈现的问题。对此的任何解决方案
Ponleu

1
@Ponleu您可以使用useMemoReact提供的挂钩来记住ContentThatGoesAboveTheFlatList组件,以避免重新渲染。此处的更多信息:reactjs.org/docs/hooks-reference.html#usememo如果有帮助,请告诉我。:)
Afraz Hussain

8

以防万一这对某人有帮助,这就是我解决此错误的方法。

我在FlatList里面嵌套了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>
    );
}

并且ScrollView通过使用FlatList渲染了我需要的所有内容来摆脱了,从而摆脱了警告:

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

查看文档中的示例,我从以下位置更改了容器:

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

至:

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

所有这些警告都消失了。


6
如果我在FlatList内部上方渲染内容ScrollView并希望该内容可滚动怎么办?
蓬留路

有两个相邻的可滚动视图并不是很好的用户体验。我会尝试像这样嵌套它:'<View> <ScrollView> <Content /> </ ScrollView> <FlatList ... /> </ View>'(未测试)
Variag

我很确定FlatList不会创建另一个滚动,除非我们将其包装在具有指定高度的容器旁边。
蓬留勒

1
我和@Ponleu有同样的问题。我在ScrollView里面有一些内容,然后在FlatList里面ScrollView。我希望整个屏幕一起滚动。
David Schilling

2
如何在Android中解决此问题?
MD。IBRAHIM KHALIL TANIM


0

出现警告是因为ScrollViewFlatList共享相同的逻辑,如果FlatList在内部运行ScrollView,则重复

顺便说一句SafeAreaView对我不起作用,唯一的解决方法是

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

错误消失


0

我尝试了一些方法来解决此问题,包括ListHeaderComponentListFooterComponent,但这都不适合我。

我想要实现的布局就是这样,并且我想滚动一次。

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

首先,我要感谢 这个问题和评论,这给了我很多想法。

我在想 ListHeaderComponent平面列表上方的位置,但是由于我Flatlist的方向是专栏,因此我想要放置的标题位于Flatlist:()的左侧

然后我不得不尝试一下VirtualizedList-backed。我只是试图打包所有组件VirtualizedList,在其中renderItems给出索引,然后可以有条件地将组件传递给renderItems

我本可以使用进行此操作Flatlist,但尚未尝试过。
最后看起来像这样。

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

当然可以滚动整个屏幕


-6

使用时会出现此问题 <FlatList /><ScrollView>相同方向的内部。

要解决此问题,只需在您的FlatList中添加“水平”即可:

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

注意:您的FlatList将水平呈现


您误解了这个问题
Giorgi Gvimradze
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.