Hugo Laplace
Hugo Laplace

Reputation: 617

React-Native huge memory usage & crash from flatlist iOS only

My app fetch a few hundreds of items from a server, then loads this data in the flatlist 5 item by 5 item onEndReached. However, when I try to scroll for a few dozen items, my app doesn't respond to onPress (outside the flatlist) anymore, and the memory usage start to blast off leading to a crash :

Click here to see image of memory usage

I tried everything, from using getItemLayout, PureComponent, maxToRenderPerBatch, windowSize, I removed all images from my item, all touchable but still can't get over this problem.

I'm of course running my app in release mode.

I don't know how to solve this as it only happens on iOS and I have only a little knowledge on iOS dev (i'm an android guy...).

Here is the code for my item :

import React, { PureComponent } from 'react';
import {
  View, Text, TouchableOpacity, StyleSheet, Image, ImageBackground, FlatList
} from 'react-native';
import globalStyle from '../globalStyle';
import MaterialCommunityIcon from 'react-native-vector-icons/MaterialCommunityIcons';
import consts from '../utils/consts';
import { formatDistance, formatPriceRange, parseTime, formatTime } from '../utils/utils';
import ItemOffer from './ItemOffer';
import Offer, { STATE_ENUM } from '../entities/Offer';
import LinearGradient from 'react-native-linear-gradient';
import FontAwesomeIcon from 'react-native-vector-icons/FontAwesome';
import { AppEventsLogger } from 'react-native-fbsdk';


export default class ItemShop extends PureComponent {

  constructor(props) {
   super(props);
   this.state = {
     shopIdx: this.props.shopIdx,
     liked: this.props.liked,
     selectedOfferIdx: 0,
     currentOffer: this.props.offers[0],
     offers: this.props.offers
   };
  }



  render() {
    return (
      <View style={{marginTop: 5, marginBottom: 10,
        alignItems:"stretch", marginLeft: 10,
        marginRight: 10, overflow: "hidden", backgroundColor: "transparent", height: 300}}>
        <TouchableOpacity
        onPress={() => {
          this.props.onPressShop(this.state.shopIdx);
        }}
        >
          <View
          style={{flexDirection: "row", justifyContent: "space-between", alignItems:"center", height: 50, backgroundColor: globalStyle.colors.bg}}>
            <View>
              <Text style={[globalStyle.style.h1, {fontFamily: globalStyle.fonts.AvertaBold}]}>{this.props.name}</Text>
              <Text style={globalStyle.style.p}>{this.props.food} - {formatPriceRange(this.props.price)} </Text>
            </View>
            <View style={{flexDirection: "row", alignItems:"center"}}>
              <Text style={[globalStyle.style.p, {marginRight: 5}]}>{formatDistance(this.props.distance)}</Text>
              <MaterialCommunityIcon name={'map-marker-radius'} size={20} color={globalStyle.colors.darkGray} />
            </View>
          </View>
        </TouchableOpacity>
      </View>
    );
  }
}

The code for my flatlist :

    <FlatList
      ref={(ref)=> this.shopList = ref }
      data={this.state.shops}
      initialNumToRender={4}
      onScrollBeginDrag={() => {
        this.setState({dragging: true});
      }}
      onScrollEndDrag={() => {
        this.setState({dragging: false});
      }}
      getItemLayout={(data, index) => (
        {length: 315, offset: 315 * index, index}
      )}
      onEndReached={this.loadMore}
      renderItem={this.renderItem}
      refreshControl={
        <RefreshControl
            refreshing={Platform.OS === 'ios' ? false : this.state.loading}
            onRefresh={this.getShops}
            tintColor={Platform.OS === 'ios' ? "transparent" : globalStyle.colors.orange}
         />
      }
    />

And the code for my renderItem function if needed:

  renderItem = ({item, index}) => (
    <ItemShop
    onPressShop={this.onPressShop}
    onPressWiniit={this.toggleModal}
    onPressLike={this.onPressLike}
    distance={item.distance}
    shopIdx={index}
    name={item.NAME}
    food={item.FOOD}
    price={item.PRICE_RANGE}
    offers={item.OFFERS}
    liked={item.liked}
    />
  );

However, if change my ItemShop render function to the following, it IS working :

  render() {
    return (
      <View style={{marginTop: 5, marginBottom: 10,
        alignItems:"stretch", marginLeft: 10,
        marginRight: 10, overflow: "hidden", backgroundColor: "transparent", height: 300}}>

              <Text style={[globalStyle.style.h1, {fontFamily: globalStyle.fonts.AvertaBold}]}>{this.props.name}</Text>

      </View>
    );
  }

I could really use help or confirmed as bug here as my due date is really soon :(

Thanks !

Upvotes: 3

Views: 3916

Answers (2)

Osama Shakir
Osama Shakir

Reputation: 26

the workaround would be to use the simple map with SCROLLVIEW this bug cost me a week dont know why Fb couldnt fix the flatlist issue after this many release i have been reading about this since it started its the reason many people shifted to flutter

Upvotes: 0

Yasen
Yasen

Reputation: 1

I think you could try these steps: 1.Profile the memory heap with debugger tools, and try to figure out what are retained in the heap 2.Specify a static keyExtractor(item.id or item.name) for your flatlist to improve performance

Upvotes: 0

Related Questions