reactjsreact-nativekeyjsxreact-native-flatlist

React-Native FlatList Each child in a list should have a unique "key" prop, I've already given keys to all mapped elements


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

Solution

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