Home > Software engineering >  React Native FlatList display on Scroll
React Native FlatList display on Scroll

Time:12-20

I'm making a flatlist in wich I display the informations on the user scroll. But I don't know why I got this error :

ERROR Warning: Encountered two children with the same key, 4. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.

I don't really know why I got some " key duplication ". There is my code :

 const getProducts = (itemId, check, multiSliderValue, offset) => {
    return new Promise((resolve, reject) => {
      dispatch(
        authAction.GetAllProducts(
          itemId,
          check,
          brand,
          multiSliderValue,
          offset
        )
      ).then((response) => {
        // faites une copie de la liste de données avant de l'utiliser comme source pour l'opérateur de décomposition
        const updatedList = [...informations];
        let counter = informations.length;
        const newArray = response.array.map((item) => ({
          ...item,
          key: counter  , // utilisez un compteur incrémental comme clé unique
        }));
        if (newArray.length > 0) {
          setInformations([...updatedList, ...newArray]);
          setOffset(offset   5);
        }
        setIsLoading(false);
        resolve(newArray);
      });
    });
  };

 const loadMoreData = () => {
    if (isLoading) {
      return; // empêche les appels multiples à la fonction de chargement de données
    }

    console.log(itemId, check, multiSliderValue, offset   5);
    setIsLoading(true);
    getProducts(itemId, check, multiSliderValue, offset)
      .then((response) => {
        if (response) {
          // mettez à jour votre liste de données avec les nouvelles données
          setInformations([...informations, ...response]);
          // mettez à jour l'offset
          setOffset(offset   5);
        } else {
          console.log("NO RESPONSE");
        }
      })
      .catch((error) => {
        console.log("error: ", error);
      })
      .finally(() => {
        setIsLoading(false);
      });
  };

there is my FLatlist :

<FlatList
          onEndReachedThreshold={0.5}
          onEndReached={loadMoreData}
          ListFooterComponent={isLoading ? <ActivityIndicator /> : null}
          style={{top: "2%"}}
          data={informations}
          renderItem={({item}) => (
            <View style={styles.Products}>
              <TouchableOpacity
                onPress={() =>
                  navigation.navigate("descriptionProduct", {
                    data: item,
                  })
                }
              >
                <View style={{width: "40%", height: "60%"}}>
                  <Image
                    style={styles.imageProduct}
                    source={{uri: item.image_url}}
                  />
                </View>
                <View style={styles.productInfos}>
                  <View style={{width: "60%", height: "30%"}}>
                    <Text
                      style={{
                        fontSize: 15,
                        bottom: "340%",
                      }}
                    >
                      {item.titre}
                    </Text>
                  </View>
                  <View
                    style={{
                      display: "flex",
                      flexDirection: "row",
                      bottom: "1%",
                    }}
                  >
                    <Text style={{color: "grey"}}>à partir de </Text>
                    <Text style={styles.price}>{item.prix} €</Text>
                    <Text style={{left: "50%", color: "grey"}}>
                      {item.boutiqueCpt} offres
                    </Text>
                  </View>
                </View>
              </TouchableOpacity>
            </View>
          )}
        />
      )}

And at the start of the page I'm using this hook :

  useEffect(() => {
    if (isLoading) {
      return; // empêche les appels multiples à la fonction de chargement de données
    }

    getBrands(itemId);
    getProducts(itemId, check, multiSliderValue, offset);
    setIsLoading(true);
  }, [dispatch]);

I'm searching since many hours but I don't found the solution so if someone could explain to me. Thanks you in advance.

CodePudding user response:

Add this to flatlist:

keyExtractor={(item, index) => item.key} //here key should be in your information which is unique for each data item in the information

or

keyExtractor={(item, index) => index}

CodePudding user response:

It is complaining due to the fact that the key you're using is sometimes the same. In the code block I don't really see you using a key however. Take note that the key is internally used for some optimisations. See documentation for more details how to add the key. In short add the key extractor method that will return the unique identifier for your items

(item: object, index: number) => string;

React native documentation

Not sure if this is the entire code but if you have a unique value for the items you're rendering over considering adding it, this should stop the warning from happening.

  • Related