ทำซ้ำพื้นเมืองคอนเทนเนอร์อื่นที่ได้รับการสนับสนุน VirtualizedList


38

หลังจากอัปเกรดเป็น 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

คำตอบ:


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 scroll container: ScrollViewและFlatList- คุณจะได้รับพฤติกรรมการเลื่อนที่ไม่สอดคล้องกัน วิธีการนำเสนอในคำตอบนี้ให้ผลลัพธ์ในคอนเทนเนอร์เลื่อนเพียง 1 รายการและในส่วนหัว / ท้ายกระดาษคุณสามารถใส่มุมมองใดก็ได้ไม่ว่าจะซับซ้อนเพียงใด
Variag

ฉันใช้องค์ประกอบของฟังก์ชั่นและได้รับ ContentThatGoesAboveTheFlatList ปัญหาการแสดงผลซ้ำ ทางออกใด ๆ ในเรื่องนี้
Ponleu

1
@Ponleu คุณสามารถบันทึกส่วนประกอบ ContentThatGoesAboveTheFlatList ของคุณโดยใช้useMemohook ที่จัดทำโดย React เพื่อหลีกเลี่ยงการแสดงซ้ำ ข้อมูลเพิ่มเติมที่นี่: 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และต้องการเนื้อหาที่จะเป็นเลื่อน?
Ponleu

ประสบการณ์การใช้งานของผู้ใช้ไม่ดีนักที่จะมีมุมมองที่เลื่อนได้สองมุมมอง ฉันจะพยายามทำมันแบบนี้: '<View> <ScrollView> <Content /> </ScrollView> <FlatList ... /> </View>' (ไม่ได้ทดสอบ)
Variag

ฉันค่อนข้างมั่นใจว่า FlatList จะไม่สร้างสโครลอื่นเว้นแต่เราจะใส่มันไว้ในคอนเทนเนอร์ที่มีความสูงที่ระบุ
Ponleu

1
ฉันมีปัญหาเช่นเดียวกับ @Ponleu ฉันมีScrollViewภายในที่เนื้อหาบางส่วนและจากนั้นยังอยู่ภายในFlatList ScrollViewและฉันต้องการให้ทั้งหน้าจอเลื่อนพร้อมกัน
David Schilling

2
วิธีแก้ปัญหานี้ใน android ??
นพ. อิบราฮิมคาลิลทานิม

0

ในความคิดของฉันฉันสามารถใช้แผนที่แทน FlatList แต่ในกรณีของฉันฉันไม่ต้องการแสดงรายการขนาดใหญ่ การไม่ใช้ FlatList อาจทำให้เกิดปัญหาด้านประสิทธิภาพ ดังนั้นฉันใช้สิ่งนี้เพื่อระงับคำเตือนhttps://github.com/GeekyAnts/NativeBase/issues/2947#issuecomment-549210509


0

คำเตือนจะปรากฏขึ้นเพราะScrollViewและFlatListแบ่งปันตรรกะเดียวกันหากFlatListทำงานภายในScrollViewก็จะเป็นการทำซ้ำ

โดยวิธีการSafeAreaViewไม่ได้ผลสำหรับฉันวิธีเดียวที่จะแก้ไขคือ

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

ข้อผิดพลาดจะหายไป


0

ฉันพยายามแก้ไขวิธีนี้รวมถึงListHeaderComponentหรือListFooterComponentแต่ก็ไม่เหมาะสำหรับฉัน

เลย์เอาต์ที่ฉันต้องการเพื่อให้บรรลุเป็นเช่นนี้และฉันต้องการเลื่อนในครั้งเดียว

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

ครั้งแรกที่ฉันอยากจะบอกว่าขอบคุณที่นี้ปัญหาและความคิดเห็นซึ่งให้ฉันพวงของความคิด

ฉันกำลังคิดถึงListHeaderComponentสถานที่เหนือ Flatlist แต่เนื่องจากFlatlistทิศทางของฉันคือคอลัมน์ส่วนหัวที่ฉันต้องการวางจึงอยู่ทางซ้ายของFlatlist:(

จากนั้นผมได้ลองในVirtualizedList-backedสิ่งที่ ฉันพยายามที่จะแพ็คทุกองค์ประกอบในการVirtualizedListที่จะช่วยให้ดัชนีและมีฉันสามารถผ่านส่วนประกอบเงื่อนไขการrenderItemsrenderItems

ฉันสามารถใช้งานได้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>

NB: FlatList ของคุณจะแสดงในแนวนอน


คุณเข้าใจคำถามผิด ๆ
Giorgi Gvimradze
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.