2

NOTE: I do understand the importance of keys in arrays. Normally I use .map for repeating over an array and use the index variable .map provides. In my case I have no access to any index variable. I want to know a better way than manually adding keys.

So I was doing this:

function AComponent() {
  return <div>
    <BComponent />
    <BComponent />
  </div>
}

function BComponent() {
  return [
    <h2>Title</h2>,
    <p>Description </p>
  ]
}

Which throws an error

Warning: Each child in an array or iterator should have a unique "key" prop. See https://reactjs.org/docs/lists-and-keys.html#keys for more information. in BComponent (created by AComponent)

So I needed to change the BComponent as:

function BComponent() {
  // I added the key attribute to each element in the array
  return [
    <h2 key="1">Title</h2>,
    <p key="2">Description </p>
  ]
}

Definitely, this is not the best way to fix this. I want to know what's the better way? Or is this a bug from React?

Asim K T
  • 16,864
  • 10
  • 77
  • 99
  • 3
    Possible duplicate of [Understanding unique keys for array children in React.js](https://stackoverflow.com/questions/28329382/understanding-unique-keys-for-array-children-in-react-js) – Scimonster Jan 10 '18 at 10:33
  • A better way would be to add a key to `` – paqash Jan 10 '18 at 10:39
  • simple solution will be, instead of returning array, return a div and put all the element inside that. – Mayank Shukla Jan 10 '18 at 10:42
  • @Scimonster No. I think my question is different. I do understand the importance of keys and I am adding it. If I was using a .map() I will have access to the index variable. In this case (this feature was introduced in React 16), I have to add keys manually – Asim K T Jan 10 '18 at 10:48
  • Thanks @MayankShukla. But I want to know what's the better way. – Asim K T Jan 10 '18 at 10:48
  • @AsimKT, if you want to return an array, there is none. You must define your own keys. If you don't want to wrap it in a wrapping `div` like Mayank Shukla suggests, try fragments. See here: https://stackoverflow.com/a/45434522/2030321 – Chris Jan 10 '18 at 10:49
  • Possible duplicate of [Parse Error: Adjacent JSX elements must be wrapped in an enclosing tag](https://stackoverflow.com/questions/31284169/parse-error-adjacent-jsx-elements-must-be-wrapped-in-an-enclosing-tag) – Chris Jan 10 '18 at 10:50
  • 1
    I don't think its a duplicate of any of the questions linked above. – Dangling Cruze Jan 10 '18 at 10:54

1 Answers1

3

Yes, react expects you to pass the key property to a component when it's part of an array of children.

Read more about it here: https://reactjs.org/docs/reconciliation.html#recursing-on-children

For your use-case you can add them manually like key='1' or with proper descriptive keys like key='title' and key='description'.

This adding a key prop may feel a bit awkward as we know the components here are not going to change.

To avoid array notation and manually added keys to each of the element, React v16.2 introduced another way of returning multiple elements called React.Fragment.

You can use it like so:

<>
  <h2>Title</h2>
  <p>Description </p>
</>

Or to be precise:

<React.Fragment>
  <h2>Title</h2>
  <p>Description </p>
</React.Fragment>

Also, do note that the short syntax <></> doesn't support keys or attributes.

Read more about fragments here: https://reactjs.org/docs/fragments.html

Go through this discussion on React's github to know more about this: https://github.com/facebook/react/issues/2127

I hope this helps.

Dangling Cruze
  • 3,283
  • 3
  • 32
  • 43