Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to specify a key for React children when mapping over an array

I have a method in a react Contact List component where I am returning another component. I have got it working but am curious if there is a better way to structure how I am using the key.

Specifically - I'm asking about this line of code from the method below (data is hard coded as sample to get started):

return <ShortContact contact={contact} key={contact.id}/>

Here is the code in context:

_getContacts() {
    let contactList = [
        {
            id: 1,
            fName: "aaa",
            lName: "aaaaa",
            imgUrl: "http://brainstorminonline.com/wp-content/uploads/2011/12/blah.jpg",
            email: "[email protected]",
            phone: "999999999999"
        },
        {
            id: 2,
            fName: "bbbbb",
            lName: "bbbbbbb",
            imgUrl: "https://media.licdn.com/mpr/mpr/shrinknp_200_200/bbb.jpg",
            email: "[email protected]",
            phone: "888888888888"
        },
        {
            id: 3,
            fName: "Number",
            lName: "Three",
            imgUrl: "http://3.bp.blogspot.com/-iYgp2G1mD4o/TssPyGjJ4bI/AAAAAAAAGl0/UoweTTF1-3U/s1600/Number+3+Coloring+Pages+14.gif",
            email: "[email protected]",
            phone: "333-333-3333"
        }
    ];

    return contactList.map((contact) => {
        "use strict";
        return <ShortContact contact={contact} key={contact.id}/>
    });
}

ShortContact Component Render:

class ShortContact extends React.Component {
    render() {
        return (
            <div >
                <li className="contact-short well whiteBG">
                    <img  className="contact-short-thumb" src={this.props.contact.imgUrl}/>
                    <p className="contact-short-name">{this.props.contact.fName}</p><br />
                    <p className="contact-short-email">{this.props.contact.email}</p>
                </li>
            </div>
        );
    }
}

I struggled with how to make it work and not get the warning Warning: Each child in an array or iterator should have a unique "key" prop. However I am wondering if the syntax or structure is valid and if it should be refactored.

like image 694
Mary Camacho Avatar asked May 02 '16 02:05

Mary Camacho


1 Answers

There is nothing wrong with this code. The key is required so that react knows how to render the children nodes. In fact your implementation is exactly what react requires the programmer to do. Now the details of which key to use and such can be changed, but it looks like you have the most performant solution already.

The main requirement is that the key is unique so as long as contact.id is always unique (which if its coming from a database then it will be) then you are fine.

Alternatively you can use an index on your map for the key but I wouldn't really recommend it (i'll explain below after the code snippet).

contactList.map((contact, i) => {
    return <ShortContact contact={contact} key={i}/>
});

Personally I think your approach is the best approach because it can prevent additional renders. What I mean is for instance when a new contact is returned from the server every contact row would be re-rendered because the index in the array for each contact is different (assuming you aren't treating it like a stack)... The different index with new contact data at that index would cause the re-render. Because contact.id is a static number if the data for that contact hasn't changed then react wont re-render it.

like image 59
John Ruddell Avatar answered Oct 17 '22 14:10

John Ruddell