I've followed the advice online and made sure every mapped element has a key in the parent container. My FlatList has the renderCard method, and an included keyExtractor that follows the syntax of suggested fixes from other SE questions. Still getting the error on each render.
<FlatList
data={correctionData}
keyExtractor={(item) => item.conversationId.toString()} // provides unique key for each item
renderItem={({ item, index }) =>
renderCard({
item,
index,
collapseCardsAndErrors,
setCollapseCardsAndErrors,
})
} // renders each item (card)
onEndReached={handleLoadMore} // fetch more data when scrolled to the bottom
onEndReachedThreshold={0.5} // fetch when 50% to the bottom
onScroll={handleScroll}
scrollEventThrottle={16}
refreshControl={refreshControl}
extraData={correctionData}
ListFooterComponent={
isLoadingMore ? (
<ActivityIndicator
size="small"
color={theme.colors.backgroundPrimary}
/>
) : null
} // spinner at the bottom
/>
const renderCard = ({
item: cardData,
index,
collapseCardsAndErrors,
setCollapseCardsAndErrors,
}: {
item: CorrectionDataType;
index: number;
collapseCardsAndErrors: boolean;
setCollapseCardsAndErrors: React.Dispatch<React.SetStateAction<boolean>>;
}) => {
return (
<ReviewCardContainer key={cardData.conversationId.toString()}>
{showDateSeparator && (
<DateSeparatorContainer>
<DateSeparatorLine />
<DateSeparatorText>
{formatDate({
dateTimeString: cardData.createdAt,
})}
</DateSeparatorText>
</DateSeparatorContainer>
)}
<ReviewCard
cardData={cardData}
searchQuery={searchQuery}
collapseCardsAndErrors={collapseCardsAndErrors}
setCollapseCardsAndErrors={setCollapseCardsAndErrors}
handleDeleteCard={() => handleDeleteCard(cardData.conversationId)}
key={cardData.conversationId.toString()}
/>
</ReviewCardContainer>
);
};
my ReviewCard also has a key at the parent container, and any mappings within also have keys.
ReviewCard JSX:
return (
<CardContainer key={conversationId.toString()}>
<TouchableOpacity onPress={toggleExpandCard} key={conversationId} >
SOLVED: in my ReviewCard component, I was returning one of two pieces of JSX, the second one was a fragment with no key. adding the key removed the recurrent error.
return (
<>
{word}
{!isLastWord && ' '}
</>
);
to
return (
<React.Fragment key={index}>
{word}
{!isLastWord && ' '}
</React.Fragment>
);