Search code examples
reactjsreact-nativeexporeact-native-flatlist

FlatList not scrolling due to items not having a fixed height


I am developing an application that has a feed. I am using a FlatList to render all of the items fetched from my back end server.

This is my Flatlist:

return (
      <View style={styles.flatListContainer}>
        <FlatList
          contentContainerStyle={styles.flatList}
          data={this.props.allRecommendations}
          keyExtractor={(item) => item.id.toString()}
          renderItem={(recommendationData) => (
            <RecommedationCard recommendationData={recommendationData} />
          )}
        />
      </View>
    );
  }
}

const styles = StyleSheet.create({
  activityIndicatorScreen: {
    flex: 1,
    justifyContent: "center",
    alignContent: "center",
    backgroundColor: colors.secondaryLight,
  },
  flatListContainer: {
    flex: 1,
    width: "100%",
  },
  flatList: {
    justifyContent: "center",
    alignItems: "center",
  },
});

I have noticed that my FlatList won't scroll unless I set a fixed height to my items being rendered. I do not want to do this because an item can be any height.

This is my Item component:

import React, { Component } from "react";
import { View, Text, StyleSheet, Image } from "react-native";

import colors from "../../constants/colors";

class RecommendationCard extends Component {
  renderRecommendationImages = () => {
    const recommendationImages = this.props.recommendationData.item
      .recommendation_images;
    return recommendationImages.map((recommendationImage) => (
      <Image
        key={recommendationImage.id}
        style={styles.recommendationImage}
        source={{ uri: recommendationImage.img_url }}
      />
    ));
  };

  render() {
    return (
      <View style={styles.recommendationCardContainer}>
        <View style={styles.browserInfoContainer}>
          <Image
            style={styles.browserPfp}
            source={{
              uri: this.props.recommendationData.item.browser.profile_img_url,
            }}
          />
          <View style={styles.browserInfoTextContainer}>
            <Text style={styles.browserName} numberOfLines={1}>
              {this.props.recommendationData.item.browser.first_name}{" "}
              {this.props.recommendationData.item.browser.last_name}
            </Text>
            <Text style={styles.browserLocation} numberOfLines={1}>
              {this.props.recommendationData.item.browser.city}{" "}
              {this.props.recommendationData.item.browser.state},{" "}
              {this.props.recommendationData.item.browser.country}
            </Text>
          </View>
        </View>
        <View style={styles.recommendationInfoContainer}>
          <Text style={styles.recommendationTitle}>
            {this.props.recommendationData.item.title}
          </Text>
          <Text style={styles.recommendationContent}>
            {this.props.recommendationData.item.content}
          </Text>
          {this.renderRecommendationImages()}
        </View>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  recommendationCardContainer: {
    width: 340,
    marginTop: 25,
    padding: 20,
    backgroundColor: "#fff",
    shadowColor: colors.darkColor,
    shadowOpacity: 0.15,
    shadowOffset: { height: 5, width: 0 },
    shadowRadius: 20,
    borderRadius: 5,
    elevation: 5,
  },
  browserInfoContainer: {
    width: "100%",
    flexDirection: "row",
  },
  browserPfp: {
    width: 60,
    height: 60,
    borderRadius: 10,
  },
  browserInfoTextContainer: {
    flexShrink: 1,
    height: 60,
    justifyContent: "center",
  },
  browserName: {
    marginStart: 20,
    fontSize: 16,
    fontFamily: "montserrat-semi-bold",
  },
  browserLocation: {
    marginTop: 6,
    marginStart: 20,
    fontSize: 15,
    fontFamily: "montserrat-regular",
  },
  recommendationInfoContainer: {
    flexShrink: 1,
    width: "100%",
    marginTop: 20,
  },
  recommendationTitle: {
    fontSize: 17,
    fontFamily: "montserrat-semi-bold",
  },
  recommendationContent: {
    marginTop: 10,
    fontSize: 15,
    fontFamily: "montserrat-regular",
  },
  recommendationImage: {
    marginTop: 10,
    width: "100%",
    height: "100%",
  },
});

export default RecommendationCard;

Is there anyway I can render these items without setting a fixed height? Thanks.


Solution

  • the problem is with your recommendationImage height. height: 100% gives the element 100% height of its parent container, that is why your problem was solving by giving a fixed height to your items. give a height to your recommendationImage instead of "100%", then you wont need a fixed height for your items

     recommendationImage: {
        marginTop: 10,
        width: "100%",
        height: 200,
    }