Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

228
Views
FlatList exceeds its container with its content: How to make FlatList with fixed height

I have a <FlatList />. Within this <FlatList /> I have another <FlatList />. The nested <FlatList /> gives me some odd behavior. It exceeds the margins of its container. As you can see, the Flags are going over the yellow box, which represent the bounds of the <FlatList />.

Here is a Snack https://snack.expo.dev/@stophfacee/nested-flatlist which reproduces the problem.

Please note: The animation (when touching the hotpink rectangle) does not work properly. I am not sure why. However, I still included it because I am not sure if that might be the problem.

about 4 years ago · Juan Pablo Isaza
3 answers
Answer question

0

This might be the result you wanted. Please check this once!

import React, { useState } from 'react';
import {
  View,
  StyleSheet,
  Animated,
  Dimensions,
  TouchableOpacity,
  Text,
  ScrollView,
} from 'react-native';
import Constants from 'expo-constants';
import CountryFlag from 'react-native-country-flag';
import { FlatList } from 'react-native-gesture-handler';

export default function App() {
  const _renderFlag = (country) => {
    return (
      <TouchableOpacity onPress={() => console.log('Flag touched')}>
        <CountryFlag
          isoCode={'NZ'}
          size={50}
          style={{ alignSelf: 'flex-end' }}
        />
      </TouchableOpacity>
    );
  };

  const _createCard = (card, index) => {
    return (
      <View style={styles.card} key={index}>
        <TouchableOpacity
          style={styles.touchable}
          onPress={() => console.log('toggle')}>
          <Text>{card}</Text>
        </TouchableOpacity>
        <View style={{ height: 200 }}>
          <FlatList
            nestedScrollEnabled={true}
            style={{ marginTop: 20, backgroundColor: 'yellow' }}
            columnWrapperStyle={{
              justifyContent: 'space-around',
            }}
            ItemSeparatorComponent={() => <View style={{ margin: 10 }}/>}
            numColumns={3}
            data={[
              1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
            ]}
            renderItem={_renderFlag}
            keyExtractor={(item, index) => index.toString()}
            getItemLayout={(data, index) => ({
              length: 50,
              offset: 50 * index,
              index,
            })}
          />
        </View>
      </View>
    );
  };

  return (
    <View style={{ flex: 1 }}>
      <FlatList
        style={{ margin: 20 }}
        data={['a', 'b', 'c']}
        keyExtractor={(item, index) => index.toString()}
        renderItem={({ item, index }) => _createCard(item, index)}
      />
    </View>
  );
}

const styles = StyleSheet.create({
  card: {
    borderColor: 'red',
    borderWidth: 2,
    padding: 8,
    marginBottom: 15,
  },
  touchable: {
    backgroundColor: 'hotpink',
    height: 50,
    width: '100%',
    justifyContent: 'center',
    alignItems: 'center',
  },
});

Working Example

about 4 years ago · Juan Pablo Isaza Report

0

I'm not very good with react native, nor can I actually see your issue, however you mentioned that it's going over the container. I had a look at your code and I know in normal css/web your styling won't work.

You have a <FlatList and you've given it a style for style={styles.container}. That container's style is:

container: {
  paddingTop: 50,
  height: '100%',
  widht: '100%',
}

There you're telling the container to be height: 100% and then you're also telling it to have a padding of 50. That will result in a total height of 100% + 50. In order to fix that you should use height: calc(100% - 50) along with your padding then it will fit perfectly.

I have no idea if that's your actual issue but I can't see how that would work unless react native is doing some whacky stuff with padding.

You've actually also done this in a couple of places, on your card you've used width: '90%' along with padding: 8, so that card will overflow its container with 6. There you also need to do width: calc(100% - 16).

This will become even more confusing if you have borderWidth: 2 and you don't have box-sizing: border-box which will result in it being even 4 more over the width of the container.

You have to be careful about the extra paddings/borders/etc you add when you've specified it's 100% width/height.

about 4 years ago · Juan Pablo Isaza Report

0

Taking into account Dan and AmerllicA's advice, this is a possible use of SectionList which seems to solve your issue:

Don't forget to import SectionList from react-native!

 const sections = [
    { title: 'Section 1', data: ['a', 'b', 'c'].map((card, index) => _createCard(card, index)) },
    { title: 'Section 2', data: ['a', 'b', 'c'].map((card, index) => _createCard(card, index)) },
    { title: 'Section 3', data: ['a', 'b', 'c'].map((card, index) => _createCard(card, index)) },
  ];

  return (
    <SectionList
      initialNumToRender={2}
      contentContainerStyle={{ alignItems: 'center' }}
      style={styles.container}
      sections={sections}
      renderItem={(item) => {
        return item.item;
      }}
      renderSectionHeader={({ section: { title } }) => (
        <View style={{ backgroundColor: 'pink', width:200,  alignItems: 'center', justifyContent: 'center', height: 50 }}>
          <Text>{title}</Text>
        </View>
      )}
    />
  );
about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!