Reputation: 2624
I don't find the way to type a FlatList in react native
export interface Category {
id: string;
title: string;
bg: string;
}
export const CATEGORIES: Category[] = [
{ id: "c1", title: "Italian", bg: "#f5428d" }
];
const Item = ({ data }: { data: Category }) => (
<View style={styles.item}>
<Text style={styles.title}>{data.title}</Text>
</View>
);
const CategoriesScreen = ({ navigation }: CategoriesScreenProps) => {
const renderItem = ({
data,
}: {
data: Category;
}) => <Item data={data} />;
return (
<FlatList
data={CATEGORIES}
keyExtractor={(item) => item.id}
renderItem={renderItem}
numColumns={2}
></FlatList>
);
};
I've got this error in renderItem props:
No overload matches this call. Overload 1 of 2, '(props: FlatListProps | Readonly<FlatListProps>): FlatList', gave the following error. Type '({ data, }: { data: Category; }) => JSX.Element' is not assignable to type 'ListRenderItem'. Types of parameters '__0' and 'info' are incompatible. Property 'data' is missing in type 'ListRenderItemInfo' but required in type '{ data: Category; }'. Overload 2 of 2, '(props: FlatListProps, context: any): FlatList', gave the following error. Type '({ data, }: { data: Category; }) => JSX.Element' is not assignable to type 'ListRenderItem
What's wrong, please?
Upvotes: 4
Views: 9394
Reputation: 1
The flatList component passes each item in your array as a variable with the name item
to the renderItem
prop. So you need to replace data
with item
, like this:
const renderItem = ({item}: {item: Category}) => <Item data={item} />;
<FlatList
data={CATEGORIES}
keyExtractor={(item) => item.id}
renderItem={renderItem}
numColumns={2}
></FlatList>
Upvotes: 0
Reputation: 111
I know this is super old, but I think I might have the solution that you were ultimately looking for. I think we must be walking through the same tutorial, because I ran into this exact same problem with the exact same typing issue.
If I'm understanding this correctly, ultimately what everyone else has said here is technically correct; the data that's used by the FlatList
is going to be a ListRenderItem<T>
. However, the individual data items wrapped by ListRenderItem
that are passed to the function you define for the renderItem
prop is actually of type ListRenderItemInfo<T>
. So, you should be able to type your function parameters like I've typed the itemData
parameter below:
import { FlatList, ListRenderItemInfo } from "react-native"
import { CategoryGridTile } from "irrelevant"
import { CATEGORIES } from "irrelevant"
import Category from "irrelevant"
export const CategoriesScreen: React.FC = () => {
return <FlatList
data={CATEGORIES}
keyExtractor={(item) => item.id}
renderItem={renderCategoryItem}
/>
}
const renderCategoryItem = (itemData: ListRenderItemInfo<Category>) => {
return <CategoryGridTile title={itemData.item.title} color={itemData.item.color} />
}
Where Category
is:
class Category {
constructor(id, title, color) {
this.id = id
this.title = title
this.color = color
}
}
I found this by digging into the definition of FlatList
and its types:
export interface ListRenderItemInfo<ItemT> {
item: ItemT;
index: number;
separators: {
highlight: () => void;
unhighlight: () => void;
updateProps: (select: 'leading' | 'trailing', newProps: any) => void;
};
}
export type ListRenderItem<ItemT> = (info: ListRenderItemInfo<ItemT>) => React.ReactElement | null;
I'm sure you've long passed this issue, but hopefully it helps someone else dealing with the same typing problem.
Upvotes: 11
Reputation: 137
You can try to write like this:
<FlatList<Category>
data={CATEGORIES}
.....
Upvotes: 0
Reputation: 49681
I think here the error desribes what went wrond :" Property 'data' is missing in type 'ListRenderItemInfo' but required in type '{ data: Category; }'."
const renderItem = ({data}: {data: Category}) => <Item data={data} />
You need to pass an object which has a "data" property, but you did not.
<FlatList
data={CATEGORIES}
keyExtractor={(item) => item.id}
renderItem= {renderItem} // {(receivesArg)=>renderItem(passArg)}
numColumns={2}
></FlatList>
or
<FlatList
data={CATEGORIES}
keyExtractor={(item) => item.id}
// import {ReactElement} from "react"
renderItem= {({ data }:data: Category;}):ReactElement => <Item data={data} />}
numColumns={2}
></FlatList>
Upvotes: 2
Reputation: 21
renderItem has the interface ListRenderItem< ItemT > , so the "data" param doesn't exist, because ListRenderItem only knows "item", "index" and "separator". Try to replace its ItemT with your data.
How do you do that? It's simple:
1st - import the ListRenderItem interface from react-native,
import { ListRenderItem } from 'react-native';
2nd - type the constant receiving the renderItem function instead of the params, replacing its "ItemT" with your item interface:
const renderItem: ListRenderItem<Category> = ({ item }) => (
<Item data={item} />
)
That's it!! Wanna check it out the code? here it is: expo snack
Upvotes: 2