React-Native: плоский список, вложенный в SectionList - PullRequest
0 голосов
/ 16 февраля 2020

Я пытаюсь сделать несколько плоских списков в списке разделов. Конечная цель такова:

A feed page that has multiple sections (Your past orders, It's lunchtime, etc..

Однако я не могу заставить его правильно визуализироваться. Он рендерит один и тот же элемент несколько раз.

            <SafeAreaView style={styles.container}>
                <SectionList
                    sections={posts}
                    keyExtractor={(item, index) => item + index}
                    renderItem={({ item }) => 
                        <FlatList
                            horizontal
                            data={posts}
                            renderItem={this.renderPosts}
                            keyExtractor={(item, index) => index}
                        />
                    }
                    renderSectionHeader={({ section: { title } }) => (
                        <Text style={styles.header}>{title}</Text>
                    )}
                />
            </SafeAreaView>





    renderPosts = (element) => {
        const { image, opinions, votes, name } = element.item;
        return (
            <Card>
                <Card.Cover source={{ uri: image }}/>
                <View>
                    <Card.Content>
                        <Title numberOfLines={1}>{name}</Title>
                    </Card.Content>

                    <Card.Content>
                        <Caption>{opinions} opinions</Caption>

                        <Headline style={{ fontSize: 10 }}>{votes}%</Headline>
                    </Card.Content>
                </View>
            </Card>
        )
    }

Объект JSON выглядит следующим образом:

        const posts = [
            {
                image: 'https://someURL.jpg',
                opinions: 4,
                votes: 87,
                name: 'Yeezy V2 350 Beluga',
                title: 'Recently uploaded',
            },
            {
                image: 'https://someURL.jpg',
                opinions: 12,
                votes: 43,
                name: 'Supreme Hoodie',
                title: 'Popular Streetwear',
            },
            {
                image: 'https://someURL.jpg',
                opinions: 12,
                votes: 90,
                name: 'Travis Scott Air Jordan 1s',
                title: 'Popular Sneakers',
            },
            {
                image: 'https://someURL.jpg',
                opinions: 4,
                votes: 87,
                name: 'Yeezy V2 350 Beluga',
                title: 'Recently uploaded',
            },
            {
                image: 'https://someURL.jpg',
                opinions: 12,
                votes: 43,
                name: 'Supreme Hoodie',
                title: 'Popular Streetwear',
            },
            {
                image: 'https://someURL.jpg',
                opinions: 12,
                votes: 90,
                name: 'Travis Scott Air Jordan 1s',
                title: 'Popular Sneakers',
            }
        ];

, и я хочу иметь разделы "Популярные кроссовки", "Популярная уличная одежда" "и" Недавно загруженные ". Объект должен отображаться под соответствующим разделом.

Пожалуйста, помогите мне понять, что я делаю неправильно. Я знаю, что sectionList должен иметь Data и Title. Но что я должен указать в качестве данных, если я хочу, чтобы несколько атрибутов отображались для каждого списка.

1 Ответ

1 голос
/ 21 февраля 2020

Вы можете сделать это без использования списка разделов. Вы можете использовать вложенный FlatList и передавать свои данные. Используя этот подход, вы можете настроить или отобразить любой макет как заголовка раздела, так и внутри тела. Вы можете изменить упомянутые коды согласно вашему требованию.

My Dummy JSON data:

var data = [
            {"id": 1,
                "title": "Passed Orders",
                "innerArray": [{
                    "id": 1,
                    "name": "Shivam Tiwari 1",
                    "star": "150",
                    "image": "https://lh3.googleusercontent.com/-sUUgyO92gjw/Xe5Df6MwaZI/AAAAAAAABDc/bYtyIbnUM8ACX83GYB7-XjFzs-HAmbE1QCK8BGAsYHg/s0/2019-12-09.jpg"
                },{
                    "id": 2,
                    "name": "Shivam Tiwari 2",
                    "star": "150",
                    "image": "https://lh3.googleusercontent.com/-OUEDRCj2dQo/Xe5Da2ZmqhI/AAAAAAAABDM/j9qXtid6afYaHNi-pwsOlVOUUdFej-dXgCK8BGAsYHg/s0/2019-12-09.jpg"
                },{
                    "id": 4,
                    "name": "Shivam Tiwari 4",
                    "star": "150",
                    "image": "https://lh3.googleusercontent.com/-ja97CHMzpN4/Xe5DcMVro2I/AAAAAAAABDQ/Z0Tht5w0TIUw37t8newe5YF6RgZYayXFwCK8BGAsYHg/s0/2019-12-09.jpg"
                }]
            },
            {
                "id": 2,
                "title": "Top People",
                "innerArray": [{
                    "id": 5,
                    "name": "Shivam Tiwari",
                    "star": "15000",
                    "image": "https://lh3.googleusercontent.com/-1NXIa1zFf7E/Xe5DyVxnkHI/AAAAAAAABDg/BTB_V4UtLNwQHqIrIXKl6cMKlutU7h3JACK8BGAsYHg/s0/2019-12-09.jpg"
                },{
                    "id": 6,
                    "name": "Shubham Tripathi",
                    "star": "45",
                    "image": "https://lh3.googleusercontent.com/-ja97CHMzpN4/Xe5DcMVro2I/AAAAAAAABDQ/Z0Tht5w0TIUw37t8newe5YF6RgZYayXFwCK8BGAsYHg/s0/2019-12-09.jpg"
                },{
                    "id": 7,
                    "name": "Kartikeya Sharma",
                    "star": "55",
                    "image": "https://lh3.googleusercontent.com/-sUUgyO92gjw/Xe5Df6MwaZI/AAAAAAAABDc/bYtyIbnUM8ACX83GYB7-XjFzs-HAmbE1QCK8BGAsYHg/s0/2019-12-09.jpg"
                },{
                    "id": 8,
                    "name": "Manoj",
                    "star": "90",
                    "image": "https://lh3.googleusercontent.com/-ulyCVQkAlK4/Xe5DZjhE9dI/AAAAAAAABDI/1zgelciGvyE67cOYEqD-XRlmO-JQAW-yACK8BGAsYHg/s0/2019-12-09.jpg"
                }]
            },
            {
                "id": 3,
                "title": "Favourite Celeb",
                "innerArray": [{
                    "id": 9,
                    "name": "Manoj Kumar Verma",
                    "star": "20",
                    "image": "https://lh3.googleusercontent.com/-OUEDRCj2dQo/Xe5Da2ZmqhI/AAAAAAAABDM/j9qXtid6afYaHNi-pwsOlVOUUdFej-dXgCK8BGAsYHg/s0/2019-12-09.jpg"
                },{
                    "id": 10,
                    "name": "Ashish",
                    "star": "10",
                    "image": "https://lh3.googleusercontent.com/-ulyCVQkAlK4/Xe5DZjhE9dI/AAAAAAAABDI/1zgelciGvyE67cOYEqD-XRlmO-JQAW-yACK8BGAsYHg/s0/2019-12-09.jpg"
                },{
                    "id": 11,
                    "name": "Balendu Tiwari",
                    "star": "150",
                    "image": "https://lh3.googleusercontent.com/-ja97CHMzpN4/Xe5DcMVro2I/AAAAAAAABDQ/Z0Tht5w0TIUw37t8newe5YF6RgZYayXFwCK8BGAsYHg/s0/2019-12-09.jpg"
                },{
                    "id": 12,
                    "name": "Amit Kumar Singh",
                    "star": "200",
                    "image": "https://lh3.googleusercontent.com/-1NXIa1zFf7E/Xe5DyVxnkHI/AAAAAAAABDg/BTB_V4UtLNwQHqIrIXKl6cMKlutU7h3JACK8BGAsYHg/s0/2019-12-09.jpg"
                }]
            }
        ]

Теперь вы можете установить его в состояние:

constructor(props) {
  super(props);

   this.state = {
        dataArr: data
    }; 

}

Вот код для Layout:

<View style={{flex: 1,width: '95%', backgroundColor: '#FFFFFF', alignSelf: 'center'}}>

                        <FlatList data={this.state.dataArr}
                        extraData={this.state}
                        // style={{marginBottom: 200}}
                          renderItem={({ item }) =>
                            <View
                              style={{marginTop: 0, width: '100%', justifyContent: 'center', alignItems: 'center'}} >
                                <View style={{paddingTop: 10,paddingBottom:0, flexDirection: 'column', justifyContent: 'center', alignItems: 'center'}}>
                                    <View style={{backgroundColor: '#000000', paddingHorizontal: 20, borderRadius: 10, elevation: 1, shadowColor: "#0000002B", shadowRadius: 3, shadowOffset: { width: 0, height: 0 }, shadowOpacity: 1.0}}>
                                        <Text style={{fontSize: 30, fontFamily: 'BebasKai', color: '#FFFFFF', textAlign: 'center', paddingHorizontal: 20, paddingVertical: 4}}>{item.title}</Text>
                                    </View>


                                    <FlatList data={item.innerArray}
                                      extraData={this.state}
                                      horizontal={true}
                                      style={{marginTop: 10}}
                                      renderItem={({ item: innerData, index }) =>
                                      <View style={{width: celebViewWidth, height: celebViewHeight, backgroundColor: "#FFFFFF", padding: 5}}>
                                        <TouchableOpacity style={{width: '100%', height: '100%', alignItems: 'center'}}>
                                            <Text style={{fontSize: 15, fontFamily: 'BebasKai', color: '#747474', textAlign: 'center',}} numberOfLines={1}>{innerData.name}</Text>
                                            <View style={{marginTop: 3, flex: 1, width: '100%',  borderRadius: 10, elevation: 1, shadowColor: "#0000002B", shadowRadius: 2, shadowOffset: { width: 0, height: 2 }, shadowOpacity: 1.0, backgroundColor: '#FFFFFF'}}>
                                                <Image 
                                                style={{width: '100%', height: '100%', borderRadius: 10}}
                                                source={{uri: innerData.image}}
                                            />
                                            </View>

                                            <View style={{backgroundColor: 'yellow', flexDirection: 'row', justifyContent: 'center', alignItems: 'center', paddingHorizontal: 5, paddingVertical: 1, borderRadius: 10, position: 'absolute', bottom: 6}}>
                                                <Image 
                                                style={{width: 12, height: 12}}
                                                source={require('../SupportingFiles/Icons/black-star.png')}
                                                />
                                                <Text style={{fontSize: 15, fontFamily: 'BebasKai', color: '#000000', textAlign: 'center', alignSelf: 'center', marginLeft: 3}}>{innerData.star}</Text>
                                            </View>

                                        </TouchableOpacity>
                                      </View>
                                    }/>

                                </View>
                            </View>
                        } />


                   </View>

Пожалуйста, дайте мне знать, если он полностью соответствует вашим требованиям. Спасибо

...