0

I am making an infinite scroll component using React's IntersectObserver. It's working great, except for the error: Warning: Encountered two children with the same key

      {allDogs?.map((dog) => (
          <Fragment key={dog?.adopterAttribute?.id}>
            {content here}
          </Fragment>

In my useEffect hook I set the dog list this way:

       setAllDogs((previousDogList) => [
          ...(previousDogList ?? []),
          ...newDogs,
        ]);

I have found this question in stack overflow, but most of the solutions talk about how setState is async, so use a function call which I am already doing. Another mentions using index for the key, but I read elsewhere that that is an anti-pattern. How else could I go about solving this?

stonerose036
  • 241
  • 3
  • 14
  • 1
    Choose a better key? Without knowing your data model I can't say what that would be, but perhaps the id of the dog, not the adopter? Or create a composite key that is always unique? – Nikki9696 Feb 15 '22 at 18:36
  • I can't answer for certain without full context. But I assume a person may adopt multiple dogs, if this is the case, then `dog.adopterAttribute.id` would duplicate eventually. As mentioned above, you should work with a unique identifier for the dog. If none is available, build a composite one when creating the key – Byron Mh Feb 15 '22 at 18:38
  • That's a warning, not an error. Can you share the `allDogs` state/data that you are attempting to render? You really just need to select a better field property to use as a React key; they need only be unique among sibling elements. – Drew Reese Feb 15 '22 at 22:12
  • These are unique keys, I think it's because of the building of the array/infinite scroll that it re-detects the same key. – stonerose036 Feb 16 '22 at 08:38
  • If React is detecting a duplicate key amongst the mapped sibling components/elements then they are by definition not unique. As others have pointed out, you are mapping dogs, so assuming no duplicate dogs then using a dog id value is better for a React key. – Drew Reese Feb 17 '22 at 05:13

1 Answers1

0

First what I did was to change the key to a template string.

key={`${dog?.adopterAttribute?.id} + ${index}`}

Then once the errors/warnings were gone, I could see the final allDogs data that was coming through, and realized there were some duplicates afterall, meaning that the error was triggered correctly.

stonerose036
  • 241
  • 3
  • 14
  • Using indexes as keys is not ideal: https://stackoverflow.com/a/59518082/15038439 If possible, giving your `dog` an id would be even better, if that's possible, – Willow Feb 17 '22 at 04:20