-1

I want to render an array of messages:

This code works:

render() {
    return this.props.messages.map((message) => (
        <Message
          key={message.id}
          message={message}
        />
    ));
}

but what is the difference if I write code like this:

render() {
    return this.props.messages.map((message) => (
        <Message
          key={generateRandomNum()}
          message={message}
        />
    ));
}

Here, the key always generates a random number when rendered. Both versions work in my application.

Also, if I have 1000 messages, do all messages get rerendered if an additional message gets added to the array of messages - this.props.messages? ---- It seems like a heavy load on the app to always rerender every message when the component receives new props.

user2456977
  • 3,830
  • 14
  • 48
  • 87

2 Answers2

3

It will re-render on the second case, because React checks the id's of the components and afterwards if their state/props has changed. So you are better off using the first case since the id's will be the same.

Murat Karagöz
  • 35,401
  • 16
  • 78
  • 107
-1

Try this:

render() {
    const messages = this.props.messages.map((message, index) => (
        <Message
          key={`message-${index}`}
          message={message}
        />
    ));

    return (<div>{messages}</div>);
}

React components must render a single top level element (in this case the div). Using the map index will also keep your keys consistent when data changes to prevent it from re-rendering everything.

bcr
  • 3,791
  • 18
  • 28
  • 3
    It's not recommendable to use the index as key https://medium.com/@robinpokorny/index-as-a-key-is-an-anti-pattern-e0349aece318 – tocqueville Jul 31 '17 at 14:52
  • Correct but this isn't using just the `index`, it's prepending the index with an identifier unique to the `Message` component. The reason you would avoid using the index is to prevent multiple components with the same key, as long as this is the only place you prepend the key with `message`, this is fine. – bcr Jul 31 '17 at 15:00
  • 1
    No, be careful, the actual reason is that the array could be modified. From the article I linked: "Let me explain, a key is the only thing React uses to identify DOM elements. What happens if you push an item to the list or remove something in the middle? If the key is same as before React assumes that the DOM element represents the same component as before. But that is no longer true.". Prepending "message-" won't change this problem. – tocqueville Jul 31 '17 at 15:02
  • Ah... so the IDs need to be added to each message in `props.messages` before they're passed as props in order to stay consistent. Uniquely generating an ID each time the `map` method runs will guarantee they're always different whereas the goal here is to make sure only new ones are different. – bcr Jul 31 '17 at 15:05
  • 1
    FYI (a) ["The key only has to be unique among its siblings, not globally unique."](https://facebook.github.io/react/docs/reconciliation.html#keys) and (b) it's still just an index key which happens to be prepended with a string. – Dave Newton Jul 31 '17 at 15:31