Search code examples
arraysjsonreact-nativereact-hooksreact-native-flatlist

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)


Solution

  • 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>;
    };