Unique key in conditional array map error

All we need is an easy explanation of the problem, so here it is.

I am conditionaly rendering rows (the last row does not have a link).

            {items.map((item, index) =>
              index !== items.length - 1 ? (
                <span>
                  <Link to={`/${item.path}`} exact>
                    {item.title}
                  </Link>
                </span>
              ) : (
                <>
                  <span>
                    {item.title}
                  </span>
                </>
              )
            )}

I cannot clear this error:

index.js:1 Warning: Each child in a list should have a unique "key" prop

On my other object maps this works:

         {items.map((item, index) =>
              index !== items.length - 1 ? (
                <span key={index}>
                  <Link to={`/${item.path}`} exact>
                    {item.title}
                  </Link>
                </span>
              ) : (
                <>
                  <span key={index}>
                    {item.title}
                  </span>
                </>
              )
            )}

Why does my key not work in this instance?

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

The top level element returned from the .map callback needs to have the key, even if the element is only a fragment wrapper:

{items.map((item, index) =>
    index !== items.length - 1 ? (
        <span key={index}>
            <Link to={`/${item.path}`} exact>
                {item.title}
            </Link>
        </span>
    ) : (
        <React.Fragment key={index}>
            <span>
                {item.title}
            </span>
        </React.Fragment>
    )
)}

Though, in this case, the fragment does nothing, so you can remove it entirely to simplify.

{items.map((item, index) =>
    index !== items.length - 1 ? (
        <span key={index}>
            <Link to={`/${item.path}`} exact>
                {item.title}
            </Link>
        </span>
    ) : (
        <span key={index}>
            {item.title}
        </span>
    )
)}

or even

{items.map((item, index) =>
    <span key={index}>
        {
            index !== items.length - 1
                ? <Link to={`/${item.path}`} exact>
                      {item.title}
                  </Link>
                : item.title
        }
    </span>
)}

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply