Render variable number of items n per row (2 in my example) in react native without using Flatlist

209 Views Asked by At

I have a case in which I am using a ScrollView.

I receive n number of paymentMediums from api which I need to render 2 per row.

With Flatlist this is just easy and I have implemented as

                                   <FlatList
                                    scrollEnabled={false}
                                    numColumns={2}
                                    data={this.state.paymentMediums}
                                    keyExtractor={item => String(item.paymentMasterIdentifier)}
                                    renderItem={({ item, index }) => (
                                        <TouchableOpacity

                                            key={item.paymentMasterIdentifier}
                                            onPress={() => this.setState({ selectedPaymentMedium: item.paymentMasterIdentifier, selectedPaymentMediumName: item.paymentMethodName })}
                                            style={[styles.checkboxView, { marginBottom: 10, width: (width - 32) / 2, alignSelf: 'center' }]}>

                                            <View style={{ borderRadius: 10, borderWidth: 3, borderColor: this.state.selectedPaymentMedium == item.paymentMasterIdentifier ? MyColors.COLOR_ACCENT : '#F1D3C3' }}>
                                                <Image
                                                    resizeMode="contain"
                                                    style={styles.paymentImage}
                                                    source={{ uri: item.imageUrl }}
                                                />
                                            </View>
                                            <Text style={{ color: this.state.selectedPaymentMedium == item.paymentMasterIdentifier ? MyColors.COLOR_ACCENT : '#7A7A7A' }}>{item.paymentMethodName}</Text>
                                        </TouchableOpacity>
                                    )}
                                /> 

However this gives the obvious warning of virtualized list should never be nested inside plain scrollview. So, I need to render them in a normal way without Flatlists.

I tried it as, {this.renderPaymentMediums()} inside render() where

 renderPaymentMediums() {
    let paymentMediums = this.state.paymentMediums;
    console.log('incoming', paymentMediums.length)
    
    for (let index = 0; index < paymentMediums.length; index += 2) {
        return (<View style={{}}>
            {     this.renderEachPaymentMediums(paymentMediums[index], paymentMediums[index + 1] ? paymentMediums[index + 1] : null)
            }
        </View>)
    }
}


renderEachPaymentMediums = (item, item2 = null) => {
    return (
        <View style={{ flexDirection: 'row', flex: 1, marginBottom: 10 }}>
            <View style={{ alignItems: 'center' }}>
                <TouchableOpacity

                    key={item.paymentMasterIdentifier}
                    onPress={() => this.setState({ selectedPaymentMedium: item.paymentMasterIdentifier, selectedPaymentMediumName: item.paymentMethodName })}
                    style={[styles.checkboxView, { width: (width - 32) / 2, }]}>

                    <View style={{ padding: 3, borderRadius: 10, borderWidth: 3, borderColor: this.state.selectedPaymentMedium == item.paymentMasterIdentifier ? MyColors.COLOR_ACCENT : '#F1D3C3' }}>
                        <Image
                            resizeMode="contain"
                            style={styles.paymentImage}
                            source={{ uri: item.imageUrl }}
                        />
                    </View>
                    <Text style={{ color: this.state.selectedPaymentMedium == item.paymentMasterIdentifier ? MyColors.COLOR_ACCENT : '#7A7A7A' }}>{item.paymentMethodName}</Text>
                </TouchableOpacity>
            </View>
            <View style={{ alignItems: 'center' }}>
                {item2 !== null && (
                    <TouchableOpacity

                        key={item2.paymentMasterIdentifier}
                        onPress={() => this.setState({ selectedPaymentMedium: item2.paymentMasterIdentifier, selectedPaymentMediumName: item2.paymentMethodName })}
                        style={[styles.checkboxView, { width: (width - 32) / 2 }]}>

                        <View style={{ padding: 3, borderRadius: 10, borderWidth: 3, borderColor: this.state.selectedPaymentMedium == item2.paymentMasterIdentifier ? MyColors.COLOR_ACCENT : '#F1D3C3' }}>
                            <Image
                                resizeMode="contain"
                                style={styles.paymentImage}
                                source={{ uri: item2.imageUrl }}
                            />
                        </View>
                        <Text style={{ color: this.state.selectedPaymentMedium == item2.paymentMasterIdentifier ? MyColors.COLOR_ACCENT : '#7A7A7A' }}>{item2.paymentMethodName}</Text>
                    </TouchableOpacity>
                )}
            </View>

        </View>

    )
}

This does not work since it returns from the first iteration of loop with the return.

So, how do I make this work.

Also, I want to ask if using using Flatlists inside ScrollView takes a toll on the performance. I have disabled the scroll of the inside Flatlist so that 2 scrolling behaviours dont overlap and hence I dont get the warning.But the warning persists. Does this step do any good??

0

There are 0 best solutions below