React Native FlatList,在使用开关渲染组件时唠叨键

时间:2017-09-12 09:59:37

标签: react-native react-native-flatlist

以下是组件代码每隔20张卡片获取项目并注入广告,它使用分页,当用户到达列表底部时,卡片将被添加到现有数据中:

// every 20 cards, inject an advertisment
var modulusCount = 0;
if ((this.state.labels.length - modCount) % 20 === 0) {
                    this.state.labels.push({type: 'ad'});
                    modulusCount++;
                }

_renderItem = ({item}) => {
    switch (item.type) {
        case 'label':
            return <Card key={item._id} style={styles.card}>
                <CardTitle title={item.description}/>
                <TouchableOpacity style={styles.image} onPress={() => this._showImage(item.imagepath, item.upvotes, item._id)} activeOpacity={0.7}>
                    <CardImage seperator={false} id={item._id} inColumn={false} source={{uri: item.imagepath}}/>
                </TouchableOpacity>
            </Card>;
        case 'ad':
            return (this.state.fbad && this.state.ads ?
                <View key={item._id}>
                    <Card style={styles.card}>
                        <CardTitle title={'Sponsored'}/>
                        <BannerView
                            placementId={placementId}
                            type="large"
                            style={{width: 100}}
                            onPress={() => console.log('click')}
                            onError={this.onBannerAdError}
                        />
                    </Card>
                </View>
                : null );
        default:
            return null;
    }
};

             <View style={styles.view}>
                    <FlatList
                        data={this.state.labels}
                        keyExtractor={this._keyExtractor}
                        renderItem={this._renderItem}
                        onScroll={this._onScroll}
                        refreshing={this.state.refreshing}
                        onRefresh={this.handleRefresh}
                        onEndReached={this.handleLoadMore}
                        onEndReachedThreshold={0.1}
                        onMomentumScrollBegin={() => {
                            this.onEndReachedCalledDuringMomentum = false;
                        }}
                        removeClippedSubviews={true}
                        ListFooterComponent={this.renderFooter}
                    />
                </View>
            </View>

一切正常,广告每20个项目展示一次,但RN会抱怨密钥Warning: Each child in an array or iterator should have a unique "key" prop.

“广告”类型的关键肯定会出现问题,我做错了什么?我如何才能使“广告”类型密钥与众不同?我通过添加shortid.generate() npm模块尝试了几种方法,并在推送像this.state.labels.push({key: shortid.generate(), type: 'ad'})这样的数组时注入一个键,然后在key={item.key}组件中设置Card但是根本没有运气

3 个答案:

答案 0 :(得分:1)

请确保item._id对于每个项目都是唯一的。

答案 1 :(得分:0)

如果您有modulusCount / modCount,那么您是否只能拥有类似

的内容
`${modulusCount}_key`

作为关键?

答案 2 :(得分:0)

似乎我正在使用keyExtractor prop错误的方式,我使用_keyExtractor = (item, index) => item.id,我将其更改为_keyExtractor = (item, index) => index;,从{{1}内的两张卡中删除key={}道具卡组件,它的工作原理应该如此。