Reputation: 164
So in my react native app for some weird reason my app keeps telling me that Warning: Each child in a list should have a unique "key" prop
but why?
Here is the code that shows the problem:
const TabBarIcon = ({ onPress, options, iconName, isFocused }) => {
return (
<Pressable
onPress={() => onPress()}
testID={options.tabBarTestID}
accessibilityRole="button"
style={({ pressed }) => [
styles.bottomTabNavigationButtonStyling,
{
backgroundColor: pressed ? 'rgba(255, 255, 255, 0.28)' : '#EA3345',
},
]}>
{isFocused ? (
<Icon name={iconName} size={RFPercentage(5)} color="white" />
) : (
<Icon name={iconName} size={RFPercentage(4)} color="white" />
)}
</Pressable>
);
};
const MyTabBar = ({ state, descriptors, navigation }) => {
return (
<View style={styles.bottomTabNavigatorStyling}>
{state.routes.map((route, index) => {
const isFocused = state.index === index;
const { options } = descriptors[route.key];
const onPress = () => {
const event = navigation.emit({
type: 'tabPress',
target: route.key,
});
if (!isFocused && !event.defaultPrevented) {
navigation.navigate(route.name);
}
};
return (
<>
/****************************************Problem Part
{index === 0 && (
<TabBarIcon
key="home"
onPress={() => onPress()}
options={options}
iconName="home"
isFocused={isFocused}
/>
)}
{index === 1 && (
<TabBarIcon
key="tasks"
onPress={() => onPress()}
options={options}
iconName="tasks"
isFocused={isFocused}
/>
)}
{index === 2 && (
<TabBarIcon
key="statistics"
onPress={() => onPress()}
options={options}
iconName="history"
isFocused={isFocused}
/>
)}
/*******************************************
</>
);
})}
</View>
);
};
please tell me what is happening. And if I forgot to mention something please do tell. I have sort bordered the part were it shows the error. It keeps saying that Each child in a list should have a unique key even thought my items are not in a list? And even if they were in a list, the key property is completely diffrent so why the problem?
Upvotes: 1
Views: 153
Reputation: 26
You have to put the key
prop on the top element.
in your case you have to set key prop on <React.Fragment>
, TabBarIcon
is not the top element.
for example you can do it like below
return (
<React.Fragment key={'route'+index}>
/****************************************Problem Part
{index === 0 && (
<TabBarIcon
onPress={() => onPress()}
options={options}
iconName="home"
isFocused={isFocused}
/>
)}
{index === 1 && (
<TabBarIcon
onPress={() => onPress()}
options={options}
iconName="tasks"
isFocused={isFocused}
/>
)}
{index === 2 && (
<TabBarIcon
onPress={() => onPress()}
options={options}
iconName="history"
isFocused={isFocused}
/>
)}
/*******************************************
</React.Fragment>
);
you can also do the same with FlatList
MyTabBar
component would be something like this
const MyTabBar = ({ state, descriptors, navigation }) => {
const _renderItem = ({ route, index }) => {
const isFocused = state.index === index;
const { options } = descriptors[route.key];
const onPress = () => {
const event = navigation.emit({
type: 'tabPress',
target: route.key,
});
if (!isFocused && !event.defaultPrevented) {
navigation.navigate(route.name);
}
};
return (
<TabBarIcon
key="home"
onPress={() => onPress()}
options={options}
iconName="home"
isFocused={isFocused}
/>
);
};
return (
<View style={styles.bottomTabNavigatorStyling}>
<FlatList
data={state.routes}
renderItem={_renderItem}
keyExtractor={(item, index) => 'TabBarIcon' + index}
/>
</View>
);
};
Upvotes: 1