Search code examples
react-nativescrollviewexporeact-native-flatlist

Multiple FlatList wrapped in ScrollView


I'm trying to use flatlist in a global scrollview, but, I have more than 300 items to list for each FlatList. So, the screen become really slow and to push another button, I need to wait like 30 second before the navigation to the other component.

I tried to use onEndReached.. On the different flatlist, but, i make them no scrollable because the fusion of all make a sort of grid. Use page system don't work too. The best thing I could do is to continue to load the FlatList items by using the scrollview (If I scroll it, then load some other results...). But I really don't know how to achieve it.

Here is the entire scrollview with all FlatList in :

<ScrollView refreshControl={
              <RefreshControl
                refreshing={this.state.refreshing}
                onRefresh={this._onRefresh}
              />
            }>
              <View style={styles.scrollContainer}>
                    <View style={styles.headerView}>
                      <Icon name="stack-overflow" style={styles.titleIcon}/>
                      <Text style={{fontSize:20, marginTop:15, marginLeft:13}}>{I18n.t("ingHeadText")}</Text>
                      <TouchableHighlight style={{position: 'absolute', right:30}} onPress={() => this.props.navigation.navigate('CreateProduct')}>
                        <Icon name="plus" style={[styles.titleIcon, {color:'#2578cf', fontSize: 25}]}/>
                      </TouchableHighlight>
                    </View>
                    <View style={styles.orderList}>
                      <ScrollView horizontal={true}>
                        <View style={styles.columnView}>
                          <View style={[styles.columnHeader, {width:125}]}>
                            <Text style={{ fontWeight: 'bold' }}>{I18n.t("ingBoardNomHead")}</Text>
                          </View>
                          <FlatList
                            data={state.tableProduct}
                            keyExtractor={item => item.product_id + ""}
                            renderItem={({ item }) =>
                            <TouchableHighlight onPress={() => this.props.navigation.navigate('EditProduct', {productId: item.product_id, productName: item.product_name})} underlayColor="white">
                              <View style={[styles.columnRow, {width:125}]}>
                                <Text>
                                  {`${item.product_name} `}
                                </Text>
                              </View>
                            </TouchableHighlight>}
                            scrollEnabled={false}
                          />
                        </View>


                        <View style={styles.columnView}>
                          <View style={styles.columnHeader}>
                            <Text style={{ fontWeight: 'bold', textAlign: 'center' }}>{I18n.t("ingBoardLstBuHead")}</Text>
                          </View>
                          <FlatList
                            data={state.tableProduct}
                            keyExtractor={item => item.product_id + ""}
                            renderItem={({ item }) =>
                            <TouchableHighlight onPress={() => this.props.navigation.navigate('EditProduct', {productId: item.product_id, productName: item.product_name})} underlayColor="white">
                              <View style={styles.columnRow}>
                                <Text style={{textAlign: 'center'}}>
                                  {`${(item.last_prix|| '')} `}
                                </Text>
                              </View>
                            </TouchableHighlight>}
                            scrollEnabled={false}
                          />
                        </View>

                        <View style={styles.columnView}>
                          <View style={styles.columnHeader}>
                              <Text style={{ fontWeight: 'bold', textAlign: 'center' }}>{I18n.t("ingBoardUnitHead")}</Text>
                          </View>
                          <FlatList
                            data={state.tableProduct}
                            keyExtractor={item => item.product_id + ""}
                            renderItem={({ item }) =>
                            <TouchableHighlight onPress={() => this.props.navigation.navigate('EditProduct', {productId: item.product_id, productName: item.product_name})} underlayColor="white">
                              <View style={styles.columnRow}>
                                <Text style={{textAlign: 'left'}}>
                                  {`${(item.unite||'')} `}
                                </Text>
                              </View>
                            </TouchableHighlight>}
                            scrollEnabled={false}
                          />
                        </View>

                        <View style={styles.columnView}>
                          <View style={styles.columnHeader}>
                              <Text style={{ fontWeight: 'bold', textAlign: 'center' }}>{I18n.t("ingBoardCateHead")}</Text>
                          </View>
                          <FlatList
                            data={state.tableProduct}
                            keyExtractor={item => item.product_id + ""}
                            renderItem={({ item }) =>
                            <TouchableHighlight onPress={() => this.props.navigation.navigate('EditProduct', {productId: item.product_id, productName: item.product_name})} underlayColor="white">
                              <View style={styles.columnRow}>
                                <Text style={{textAlign: 'left'}}>
                                  {`${(item.category||'')} `}
                                </Text>
                              </View>
                            </TouchableHighlight>}
                            scrollEnabled={false}
                          />
                        </View>

                        <View style={styles.columnView}>
                          <View style={styles.columnHeader}>
                              <Text style={{ fontWeight: 'bold', textAlign: 'center' }}>{I18n.t("ingBoardRecHead")}</Text>
                          </View>
                          <FlatList
                            data={state.tableProduct}
                            keyExtractor={item => item.product_id + ""}
                            renderItem={({ item }) => {
                              if(item.avail != null){
                                return(<TouchableHighlight onPress={() => this.props.navigation.navigate('EditProduct', {productId: item.product_id, productName: item.product_name})} underlayColor="white">
                                  <View style={styles.columnRow}>
                                    <Icon name="checkbox-marked-circle" style={{color: '#19C44B', fontSize:16, textAlign:'center'}}/>
                                  </View>
                                </TouchableHighlight>);
                              } else {
                                <TouchableHighlight onPress={() => this.props.navigation.navigate('EditProduct', {productId: item.product_id, productName: item.product_name})} underlayColor="white">
                                  <View style={styles.columnRow}>
                                  </View>
                                </TouchableHighlight>
                              }

                            }}
                            scrollEnabled={false}
                          />
                        </View>

                        <View style={styles.columnView}>
                          <View style={[styles.columnHeader, {width:125}]}>
                              <Text style={{ fontWeight: 'bold', textAlign: 'center' }}>{I18n.t("ingBoardComHead")}</Text>
                          </View>
                          <FlatList
                            data={state.tableProduct}
                            keyExtractor={item => item.product_id + ""}
                            renderItem={({ item }) =>
                            <TouchableHighlight onPress={() => this.props.navigation.navigate('Commandes')} underlayColor="white">
                              <View style={[styles.columnRow, {width:125}]}>
                                <Text style={{textAlign: 'left', color: item.couleur}}>
                                  {`${(item.etat_commande||'')} `}
                                </Text>
                              </View>
                            </TouchableHighlight>}
                            scrollEnabled={false}
                          />
                        </View>

                        <View style={styles.columnView}>
                          <View style={[styles.columnHeader, {width:125}]}>
                          </View>
                          <FlatList
                            data={state.tableProduct}
                            keyExtractor={item => item.product_id + ""}
                            renderItem={({ item }) =>
                            <View style={[styles.columnRow, {width:125}]}>
                                <Button primary style={styles.orderButton} onPress={() => this.props.navigation.navigate('OrderProduct', {productId: item.product_id, productName: item.product_name})}>
                                  <Text style={styles.orderText}>{I18n.t("ordIngComBtn")}</Text>
                                </Button>
                              </View>
                            }
                            scrollEnabled={false}
                          />
                        </View>

                        <View style={styles.columnView}>
                          <View style={styles.columnHeader}>
                              <Text style={{ fontWeight: 'bold', textAlign: 'center' }}>{I18n.t("ingBoardRupHead")}</Text>
                          </View>
                          <FlatList
                            data={state.tableProduct}
                            keyExtractor={item => item.product_id + ""}
                            renderItem={({ item }) => {
                              if(item.rupture != null){
                                return(<TouchableHighlight onPress={() => this.props.navigation.navigate('EditProduct', {productId: item.product_id, productName: item.product_name})} underlayColor="white">
                                  <View style={styles.columnRow}>
                                    <Icon name="alert-circle" style={{color: '#CC0000', fontSize:16, textAlign:'center'}}/>
                                  </View>
                                </TouchableHighlight>);
                              } else {
                                return(<TouchableHighlight onPress={() => this.props.navigation.navigate('EditProduct', {productId: item.product_id, productName: item.product_name})} underlayColor="white">
                                  <View style={styles.columnRow}>
                                  </View>
                                </TouchableHighlight>);
                              }

                            }}
                            scrollEnabled={false}
                          />
                        </View>

                        <View style={[styles.columnView, {width:50}]}>
                          <View style={[styles.columnHeader, {width:50}]}>
                            <Text style={{ fontWeight: 'bold', textAlign: 'center' }}></Text>
                          </View>
                          <FlatList
                            data={state.tableProduct}
                            keyExtractor={item => item.product_id + ""}
                            renderItem={({ item }) =>
                            <View style={styles.columnRow}>
                              <Button
                                transparent onPress={() => {
                                  Alert.alert(
                                    I18n.t("ordAlertOrdDel"),
                                    I18n.t("complOrdBoardAlertDelConfirm").concat(item.product_name).concat(" ?"),
                                    [
                                      {text: I18n.t("noWord"), onPress: () => this.props.navigation.navigate('Ingredients')},
                                      {text: I18n.t("yesWord"), onPress: () => this.deleteProduct(item.product_id)},
                                    ]
                                  );
                                }}>
                                <Icon name="trash-can-outline" style={{color:'#2578cf', fontSize:23}}/>
                              </Button>
                            </View>}
                            scrollEnabled={false}
                          />
                        </View>

                       </ScrollView>
                    </View>
                    </View>
                </ScrollView>

Somebody has an idea to achieve this and resolve my problem? Thanks.


Solution

  • Many of the props like onEndReached do not work for nested ScrollViews. To make what you require, you need to use the parent ScrollView's props.

    ScrollView doesn't have a onEndReached prop but you can manually implement it like so:

    <ScrollView onScroll={e => {
           const {layoutMeasurement, contentOffset, contentSize} = e.nativeEvent;
           const paddingToBottom = 30;
           const isCloseToBottom = layoutMeasurement.height + contentOffset.y >=
                                   contentSize.height - paddingToBottom;
           if(isCloseToBottom && !this.isLoading){ //!this.isLoading makes sure the items are loading only once per end reached.
               this.isLoading = true;
               //load more items into state here...
               this.setState({//change state}, () => (this.isLoading = false)); //make sure to set isLoading to false.
           }
    }}>
    {...your items here}
    </ScrollView>