guyman
guyman

Reputation: 197

Passing Array into FlatList React Native (Not Rendering)

So I have this array, as shown below:

const categoryData=[
        {
            id: 1,
            name: "cat1",
            icon: icons.one
        },
        {
            id: 2,
            name: "cat2",
            icon: icons.two
        },
]

I'm trying to store it in a useState const called categories, and then display categories in the data parameter within a FlatList:

const [categories, setCategories] = React.useState(categoryData)

<FlatList
    data={categories}
    keyExtractor={item => `${item.id}`}
    renderItem={renderItem}
    numColumns={4}
    contentContainerStyle={{ padding: SIZES.padding }}
/>

However, nothing renders when within the FlatList (important to note, the FlatList loads when a Modal is triggered, and the FlatList does render the items properly when data={categoryData} instead of just categories).

Thanks for the assistance.

EDIT: Here is an Expo link to depict the issue (https://snack.expo.dev/HsffYfsrc)

Upvotes: 1

Views: 805

Answers (2)

Drew Reese
Drew Reese

Reputation: 202666

In your code example you've used/referenced categoryData prior to it having been declared.

const App = () => {
  const [categories, setCategories] = React.useState(categoryData); // <-- used, undefined
  const [modalVisible, setModalVisible] = React.useState(false);

  const categoryData = [ // <-- declared here
    {
      id: 1,
      name: 'cat1',
      icon: 'test'
    },
    {
      id: 2,
      name: 'cat2',
      icon: 'test'
    },
  ];

  function renderList() {
    ...
  }

  return <SafeAreaView>{renderList()}</SafeAreaView>;
}

I don't see any internal dependencies (to the component) to require that categoryData be declared within the component. I suggest declaring it outside the component so it's declared prior to the component and in scope.

const categoryData = [ // <-- declared
  {
    id: 1,
    name: 'cat1',
    icon: 'test',
  },
  {
    id: 2,
    name: 'cat2',
    icon: 'test',
  },
];

const App = () => {
  const [categories, setCategories] = React.useState(categoryData); // <-- defined
  const [modalVisible, setModalVisible] = React.useState(false);

  function renderList() {
    ...
  }

  return <SafeAreaView>{renderList()}</SafeAreaView>;
};

Expo Snack

If categoryData is not known at compile time and is actually fetched later then provide valid initial state and load/update the category state in an useEffect hook.

Example:

const App = () => {
  const [categories, setCategories] = React.useState([]); // <-- valid initial state
  const [modalVisible, setModalVisible] = React.useState(false);

  useEffect(() => {
    ... fetch/loading logic
    setModalVisible(data); // <-- update state with fetched/loaded data
  }, []);

  function renderList() {
    ...
  }

  return <SafeAreaView>{renderList()}</SafeAreaView>;
};

Upvotes: 2

qretsar
qretsar

Reputation: 13

If you say it works when Modal is triggered, then the issue might be that your data is not ready on load. I suggest you try:

{categories && <FlatList
data={categories}
keyExtractor={item => `${item.id}`}
renderItem={renderItem}
numColumns={4}
contentContainerStyle={{ padding: SIZES.padding }}/>}

Upvotes: 0

Related Questions