Search code examples
javascriptreactjsreact-key-index

Problem with warning about unique keys for array children in React.js


Not for a first time I feel stupid but this time more so. I am building a React app based on Reddit's API. My page is receiving followedSubReddits (the subreddits I am interested in) as props from App.js which is an array of objects, e.g.:

Array(20) [ {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, … ]
​
0: Object { searchedName: "AskReddit", display_name: "AskReddit", accounts_active: 107658, … }
​​
accounts_active: 107658
​​
created_utc: 1201233135
​​
display_name: "AskReddit"
​​
header_img: "https://a.thumbs.redditmedia.com/IrfPJGuWzi_ewrDTBlnULeZsJYGz81hsSQoQJyw6LD8.png"
​​
icon_img: "https://b.thumbs.redditmedia.com/LSHrisQApf1H5F8nWShTx3_KjTOMc3R_ss3kx3XAyXQ.png"
​​
public_description: "r/AskReddit is the place to ask and answer thought-provoking questions."
​​
searchedName: "AskReddit"
​​
subscribers: 42890859
​​
title: "Ask Reddit..."
​​
url: "/r/AskReddit/"
​​
<prototype>: Object { … }
​

Then I am trying to render a card-like element for each object in the array. The parent element looks like this:

const Home = ({ followedSubReddits }) => {
  return (
    <main className={styles.mainContainer}>
      <h1>
        <div className={styles.galleryTitle}>Selected Subreddits</div>
        <div className={styles.gallerySubtitle}> (best / top / hot / controversial posts for a subreddit)</div>
      </h1>

      <div className={styles.galleryContainer}>
        {followedSubReddits.map(subr =>
          <SubredditInfoBar subr={subr} />
        )}
      </div>

    </main>
  );
};

And as children I am rendering card-like components:

export default function SubredditInfoBar({ subr }) {
  return (
    <div className={styles.subRBarContainer} key={subr.display_name}>
      {subr.display_name}
    </div >
  )
}

I can confirm that each subr.display_name (name of a subreddit from my array) is unique but even if it wasn't I am still getting the same error when I generate a key using nanoid. I have tried passing different props from the parent, random numbers etc. - no joy.

Probably the image can demonstrate the issue a bit better - I am getting the display names of each subreddit, they are unique, I am assigning them as keys to each , everything renders just right... and the warning is still appearing.

I know this will look ridiculous to some. and yes - I did a lot of research and testing but to no avail.

Btw the whole project could be found here.


Solution

  • The React key is used on the mapped component, not in the JSX the mapped component renders.

    const Home = ({ followedSubReddits }) => {
      return (
        <main className={styles.mainContainer}>
          <h1>
            <div className={styles.galleryTitle}>
              Selected Subreddits
            </div>
            <div className={styles.gallerySubtitle}>
              (best / top / hot / controversial posts for a subreddit)
            </div>
          </h1>
    
          <div className={styles.galleryContainer}>
            {followedSubReddits.map(subr =>
              <SubredditInfoBar
                key={subr.display_name} // <-- React key here
                subr={subr}
              />
            )}
          </div>
        </main>
      );
    };
    
    export default function SubredditInfoBar({ subr }) {
      return (
        <div className={styles.subRBarContainer}> // <-- not here
         {subr.display_name}
        </div >
      )
    }
    

    If after using the React key in the correct location you still have the warning then it means the mapped property you are using isn't sufficiently unique among the siblings. In this case choose a different property that guarantees uniqueness, or pre-process your data to inject a GUID property using nanoid or similar function and use this GUID as the React key.