How to create unique keys for React elements?











up vote
17
down vote

favorite
4












I am making a React app that allows you to make a list and save it, but React has been giving me a warning that my elements don't have a unique key prop (elements List/ListForm). How should I create a unique key prop for user created elements? Below is my React code



var TitleForm = React.createClass({
handleSubmit: function(e) {
e.preventDefault();
var listName = {'name':this.refs.listName.value};
this.props.handleCreate(listName);
this.refs.listName.value = "";
},
render: function() {
return (
<div>
<form onSubmit={this.handleSubmit}>
<input className='form-control list-input' type='text' ref='listName' placeholder="List Name"/>
<br/>
<button className="btn btn-primary" type="submit">Create</button>
</form>
</div>
);
}
});

var ListForm = React.createClass({
getInitialState: function() {
return {items:[{'name':'item1'}],itemCount:1};
},
handleSubmit: function(e) {
e.preventDefault();
var list = {'name': this.props.name, 'data':};
var items = this.state.items;
for (var i = 1; i < items.length; i++) {
list.data.push(this.refs[items[i].name]);
}
this.props.update(list);
$('#'+this.props.name).remove();
},
handleClick: function() {
this.setState({
items: this.state.items.concat({'name':'item'+this.state.itemCount+1}),
itemCount: this.state.itemCount+1
});
},
handleDelete: function() {
this.setState({
itemCount: this.state.itemCount-1
});
},
render: function() {
var listItems = this.state.items.map(function(item) {
return (
<div>
<input type="text" className="list-form" placeholder="List Item" ref={item.name}/>
<br/>
</div>
);
});
return (
<div>
<form onSubmit={this.handleSubmit} className="well list-form-container">
{listItems}
<br/>
<div onClick={this.handleClick} className="btn btn-primary list-button">Add</div>
<div onClick={this.handleDelete} className="btn btn-primary list-button">Delete</div>
<button type="submit" className="btn btn-primary list-button">Save</button>
</form>
</div>
)
}
});


var List = React.createClass({
getInitialState: function() {
return {lists:, savedLists: };
},
handleCreate: function(listName) {
this.setState({
lists: this.state.lists.concat(listName)
});
},
updateSaved: function(list) {
this.setState({
savedLists: this.state.savedLists.concat(list)
});
},
render: function() {
var lst = this;
var lists = this.state.lists.map(function(list) {
return(
<div>
<div key={list.name} id={list.name}>
<h2 key={"header"+list.name}>{list.name}</h2>
<ListForm update={lst.updateSaved} name={list.name}/>
</div>
</div>
)
});
var savedLists = this.state.savedLists.map(function(list) {
var list_data = list.data;
list_data.map(function(data) {
return (
<li>{data}</li>
)
});
return(
<div>
<h2>{list.name}</h2>
<ul>
{list_data}
</ul>
</div>
)
});
var save_msg;
if(savedLists.length == 0){
save_msg = 'No Saved Lists';
}else{
save_msg = 'Saved Lists';
}
return (
<div>
<TitleForm handleCreate={this.handleCreate} />
{lists}
<h2>{save_msg}</h2>
{savedLists}
</div>
)
}
});

ReactDOM.render(<List/>,document.getElementById('app'));


My HTML:



<div class="container">
<h1>Title</h1>
<div id="app" class="center"></div>
</div>









share|improve this question


















  • 1




    You can use uuid npm package. npmjs.com/package/uuid
    – RIYAJ KHAN
    Nov 13 '17 at 6:34










  • @RIYAJKHAN - If you use this package can you make one global version of const uuidv4 = require('uuid/v4'); or should you have one per component?
    – chobo2
    Jul 18 at 19:53










  • @chobo2 there is nothing like . global or local to component.You can import and use it
    – RIYAJ KHAN
    Jul 19 at 3:18










  • @RIYAJKHAN - I meant should I put it in it's own file and then export it into other components? But it sounds like there is no point doing that.
    – chobo2
    Jul 19 at 16:19










  • no need to export in other component,Just import in the component where you want to use it
    – RIYAJ KHAN
    Jul 19 at 17:06















up vote
17
down vote

favorite
4












I am making a React app that allows you to make a list and save it, but React has been giving me a warning that my elements don't have a unique key prop (elements List/ListForm). How should I create a unique key prop for user created elements? Below is my React code



var TitleForm = React.createClass({
handleSubmit: function(e) {
e.preventDefault();
var listName = {'name':this.refs.listName.value};
this.props.handleCreate(listName);
this.refs.listName.value = "";
},
render: function() {
return (
<div>
<form onSubmit={this.handleSubmit}>
<input className='form-control list-input' type='text' ref='listName' placeholder="List Name"/>
<br/>
<button className="btn btn-primary" type="submit">Create</button>
</form>
</div>
);
}
});

var ListForm = React.createClass({
getInitialState: function() {
return {items:[{'name':'item1'}],itemCount:1};
},
handleSubmit: function(e) {
e.preventDefault();
var list = {'name': this.props.name, 'data':};
var items = this.state.items;
for (var i = 1; i < items.length; i++) {
list.data.push(this.refs[items[i].name]);
}
this.props.update(list);
$('#'+this.props.name).remove();
},
handleClick: function() {
this.setState({
items: this.state.items.concat({'name':'item'+this.state.itemCount+1}),
itemCount: this.state.itemCount+1
});
},
handleDelete: function() {
this.setState({
itemCount: this.state.itemCount-1
});
},
render: function() {
var listItems = this.state.items.map(function(item) {
return (
<div>
<input type="text" className="list-form" placeholder="List Item" ref={item.name}/>
<br/>
</div>
);
});
return (
<div>
<form onSubmit={this.handleSubmit} className="well list-form-container">
{listItems}
<br/>
<div onClick={this.handleClick} className="btn btn-primary list-button">Add</div>
<div onClick={this.handleDelete} className="btn btn-primary list-button">Delete</div>
<button type="submit" className="btn btn-primary list-button">Save</button>
</form>
</div>
)
}
});


var List = React.createClass({
getInitialState: function() {
return {lists:, savedLists: };
},
handleCreate: function(listName) {
this.setState({
lists: this.state.lists.concat(listName)
});
},
updateSaved: function(list) {
this.setState({
savedLists: this.state.savedLists.concat(list)
});
},
render: function() {
var lst = this;
var lists = this.state.lists.map(function(list) {
return(
<div>
<div key={list.name} id={list.name}>
<h2 key={"header"+list.name}>{list.name}</h2>
<ListForm update={lst.updateSaved} name={list.name}/>
</div>
</div>
)
});
var savedLists = this.state.savedLists.map(function(list) {
var list_data = list.data;
list_data.map(function(data) {
return (
<li>{data}</li>
)
});
return(
<div>
<h2>{list.name}</h2>
<ul>
{list_data}
</ul>
</div>
)
});
var save_msg;
if(savedLists.length == 0){
save_msg = 'No Saved Lists';
}else{
save_msg = 'Saved Lists';
}
return (
<div>
<TitleForm handleCreate={this.handleCreate} />
{lists}
<h2>{save_msg}</h2>
{savedLists}
</div>
)
}
});

ReactDOM.render(<List/>,document.getElementById('app'));


My HTML:



<div class="container">
<h1>Title</h1>
<div id="app" class="center"></div>
</div>









share|improve this question


















  • 1




    You can use uuid npm package. npmjs.com/package/uuid
    – RIYAJ KHAN
    Nov 13 '17 at 6:34










  • @RIYAJKHAN - If you use this package can you make one global version of const uuidv4 = require('uuid/v4'); or should you have one per component?
    – chobo2
    Jul 18 at 19:53










  • @chobo2 there is nothing like . global or local to component.You can import and use it
    – RIYAJ KHAN
    Jul 19 at 3:18










  • @RIYAJKHAN - I meant should I put it in it's own file and then export it into other components? But it sounds like there is no point doing that.
    – chobo2
    Jul 19 at 16:19










  • no need to export in other component,Just import in the component where you want to use it
    – RIYAJ KHAN
    Jul 19 at 17:06













up vote
17
down vote

favorite
4









up vote
17
down vote

favorite
4






4





I am making a React app that allows you to make a list and save it, but React has been giving me a warning that my elements don't have a unique key prop (elements List/ListForm). How should I create a unique key prop for user created elements? Below is my React code



var TitleForm = React.createClass({
handleSubmit: function(e) {
e.preventDefault();
var listName = {'name':this.refs.listName.value};
this.props.handleCreate(listName);
this.refs.listName.value = "";
},
render: function() {
return (
<div>
<form onSubmit={this.handleSubmit}>
<input className='form-control list-input' type='text' ref='listName' placeholder="List Name"/>
<br/>
<button className="btn btn-primary" type="submit">Create</button>
</form>
</div>
);
}
});

var ListForm = React.createClass({
getInitialState: function() {
return {items:[{'name':'item1'}],itemCount:1};
},
handleSubmit: function(e) {
e.preventDefault();
var list = {'name': this.props.name, 'data':};
var items = this.state.items;
for (var i = 1; i < items.length; i++) {
list.data.push(this.refs[items[i].name]);
}
this.props.update(list);
$('#'+this.props.name).remove();
},
handleClick: function() {
this.setState({
items: this.state.items.concat({'name':'item'+this.state.itemCount+1}),
itemCount: this.state.itemCount+1
});
},
handleDelete: function() {
this.setState({
itemCount: this.state.itemCount-1
});
},
render: function() {
var listItems = this.state.items.map(function(item) {
return (
<div>
<input type="text" className="list-form" placeholder="List Item" ref={item.name}/>
<br/>
</div>
);
});
return (
<div>
<form onSubmit={this.handleSubmit} className="well list-form-container">
{listItems}
<br/>
<div onClick={this.handleClick} className="btn btn-primary list-button">Add</div>
<div onClick={this.handleDelete} className="btn btn-primary list-button">Delete</div>
<button type="submit" className="btn btn-primary list-button">Save</button>
</form>
</div>
)
}
});


var List = React.createClass({
getInitialState: function() {
return {lists:, savedLists: };
},
handleCreate: function(listName) {
this.setState({
lists: this.state.lists.concat(listName)
});
},
updateSaved: function(list) {
this.setState({
savedLists: this.state.savedLists.concat(list)
});
},
render: function() {
var lst = this;
var lists = this.state.lists.map(function(list) {
return(
<div>
<div key={list.name} id={list.name}>
<h2 key={"header"+list.name}>{list.name}</h2>
<ListForm update={lst.updateSaved} name={list.name}/>
</div>
</div>
)
});
var savedLists = this.state.savedLists.map(function(list) {
var list_data = list.data;
list_data.map(function(data) {
return (
<li>{data}</li>
)
});
return(
<div>
<h2>{list.name}</h2>
<ul>
{list_data}
</ul>
</div>
)
});
var save_msg;
if(savedLists.length == 0){
save_msg = 'No Saved Lists';
}else{
save_msg = 'Saved Lists';
}
return (
<div>
<TitleForm handleCreate={this.handleCreate} />
{lists}
<h2>{save_msg}</h2>
{savedLists}
</div>
)
}
});

ReactDOM.render(<List/>,document.getElementById('app'));


My HTML:



<div class="container">
<h1>Title</h1>
<div id="app" class="center"></div>
</div>









share|improve this question













I am making a React app that allows you to make a list and save it, but React has been giving me a warning that my elements don't have a unique key prop (elements List/ListForm). How should I create a unique key prop for user created elements? Below is my React code



var TitleForm = React.createClass({
handleSubmit: function(e) {
e.preventDefault();
var listName = {'name':this.refs.listName.value};
this.props.handleCreate(listName);
this.refs.listName.value = "";
},
render: function() {
return (
<div>
<form onSubmit={this.handleSubmit}>
<input className='form-control list-input' type='text' ref='listName' placeholder="List Name"/>
<br/>
<button className="btn btn-primary" type="submit">Create</button>
</form>
</div>
);
}
});

var ListForm = React.createClass({
getInitialState: function() {
return {items:[{'name':'item1'}],itemCount:1};
},
handleSubmit: function(e) {
e.preventDefault();
var list = {'name': this.props.name, 'data':};
var items = this.state.items;
for (var i = 1; i < items.length; i++) {
list.data.push(this.refs[items[i].name]);
}
this.props.update(list);
$('#'+this.props.name).remove();
},
handleClick: function() {
this.setState({
items: this.state.items.concat({'name':'item'+this.state.itemCount+1}),
itemCount: this.state.itemCount+1
});
},
handleDelete: function() {
this.setState({
itemCount: this.state.itemCount-1
});
},
render: function() {
var listItems = this.state.items.map(function(item) {
return (
<div>
<input type="text" className="list-form" placeholder="List Item" ref={item.name}/>
<br/>
</div>
);
});
return (
<div>
<form onSubmit={this.handleSubmit} className="well list-form-container">
{listItems}
<br/>
<div onClick={this.handleClick} className="btn btn-primary list-button">Add</div>
<div onClick={this.handleDelete} className="btn btn-primary list-button">Delete</div>
<button type="submit" className="btn btn-primary list-button">Save</button>
</form>
</div>
)
}
});


var List = React.createClass({
getInitialState: function() {
return {lists:, savedLists: };
},
handleCreate: function(listName) {
this.setState({
lists: this.state.lists.concat(listName)
});
},
updateSaved: function(list) {
this.setState({
savedLists: this.state.savedLists.concat(list)
});
},
render: function() {
var lst = this;
var lists = this.state.lists.map(function(list) {
return(
<div>
<div key={list.name} id={list.name}>
<h2 key={"header"+list.name}>{list.name}</h2>
<ListForm update={lst.updateSaved} name={list.name}/>
</div>
</div>
)
});
var savedLists = this.state.savedLists.map(function(list) {
var list_data = list.data;
list_data.map(function(data) {
return (
<li>{data}</li>
)
});
return(
<div>
<h2>{list.name}</h2>
<ul>
{list_data}
</ul>
</div>
)
});
var save_msg;
if(savedLists.length == 0){
save_msg = 'No Saved Lists';
}else{
save_msg = 'Saved Lists';
}
return (
<div>
<TitleForm handleCreate={this.handleCreate} />
{lists}
<h2>{save_msg}</h2>
{savedLists}
</div>
)
}
});

ReactDOM.render(<List/>,document.getElementById('app'));


My HTML:



<div class="container">
<h1>Title</h1>
<div id="app" class="center"></div>
</div>






reactjs






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Sep 17 '16 at 16:57









user1775500

3642514




3642514








  • 1




    You can use uuid npm package. npmjs.com/package/uuid
    – RIYAJ KHAN
    Nov 13 '17 at 6:34










  • @RIYAJKHAN - If you use this package can you make one global version of const uuidv4 = require('uuid/v4'); or should you have one per component?
    – chobo2
    Jul 18 at 19:53










  • @chobo2 there is nothing like . global or local to component.You can import and use it
    – RIYAJ KHAN
    Jul 19 at 3:18










  • @RIYAJKHAN - I meant should I put it in it's own file and then export it into other components? But it sounds like there is no point doing that.
    – chobo2
    Jul 19 at 16:19










  • no need to export in other component,Just import in the component where you want to use it
    – RIYAJ KHAN
    Jul 19 at 17:06














  • 1




    You can use uuid npm package. npmjs.com/package/uuid
    – RIYAJ KHAN
    Nov 13 '17 at 6:34










  • @RIYAJKHAN - If you use this package can you make one global version of const uuidv4 = require('uuid/v4'); or should you have one per component?
    – chobo2
    Jul 18 at 19:53










  • @chobo2 there is nothing like . global or local to component.You can import and use it
    – RIYAJ KHAN
    Jul 19 at 3:18










  • @RIYAJKHAN - I meant should I put it in it's own file and then export it into other components? But it sounds like there is no point doing that.
    – chobo2
    Jul 19 at 16:19










  • no need to export in other component,Just import in the component where you want to use it
    – RIYAJ KHAN
    Jul 19 at 17:06








1




1




You can use uuid npm package. npmjs.com/package/uuid
– RIYAJ KHAN
Nov 13 '17 at 6:34




You can use uuid npm package. npmjs.com/package/uuid
– RIYAJ KHAN
Nov 13 '17 at 6:34












@RIYAJKHAN - If you use this package can you make one global version of const uuidv4 = require('uuid/v4'); or should you have one per component?
– chobo2
Jul 18 at 19:53




@RIYAJKHAN - If you use this package can you make one global version of const uuidv4 = require('uuid/v4'); or should you have one per component?
– chobo2
Jul 18 at 19:53












@chobo2 there is nothing like . global or local to component.You can import and use it
– RIYAJ KHAN
Jul 19 at 3:18




@chobo2 there is nothing like . global or local to component.You can import and use it
– RIYAJ KHAN
Jul 19 at 3:18












@RIYAJKHAN - I meant should I put it in it's own file and then export it into other components? But it sounds like there is no point doing that.
– chobo2
Jul 19 at 16:19




@RIYAJKHAN - I meant should I put it in it's own file and then export it into other components? But it sounds like there is no point doing that.
– chobo2
Jul 19 at 16:19












no need to export in other component,Just import in the component where you want to use it
– RIYAJ KHAN
Jul 19 at 17:06




no need to export in other component,Just import in the component where you want to use it
– RIYAJ KHAN
Jul 19 at 17:06












5 Answers
5






active

oldest

votes

















up vote
20
down vote



accepted










There are many ways in which you can create unique keys, the simplest method is to use the index when iterating arrays.



Example



    var lists = this.state.lists.map(function(list, index) {
return(
<div key={index}>
<div key={list.name} id={list.name}>
<h2 key={"header"+list.name}>{list.name}</h2>
<ListForm update={lst.updateSaved} name={list.name}/>
</div>
</div>
)
});


Wherever you're lopping over data, here this.state.lists.map, you can pass second parameter function(list, index) to the callback as well and that will be its index value and it will be unique for all the items in the array.



And then you can use it like



<div key={index}>



You can do the same here as well



    var savedLists = this.state.savedLists.map(function(list, index) {
var list_data = list.data;
list_data.map(function(data, index) {
return (
<li key={index}>{data}</li>
)
});
return(
<div key={index}>
<h2>{list.name}</h2>
<ul>
{list_data}
</ul>
</div>
)
});


Edit



However, As pointed by the user Martin Dawson in the comment below, This is not always ideal.



So whats the solution then?



Many




  • You can create a function to generate unique keys/ids/numbers/strings and use that

  • You can make use of existing npm packages like uuid, uniqid, etc

  • You can also generate random number like new Date().getTime(); and prefix it with something from the item you're iterating to guarantee its uniqueness

  • Lastly, I recommend using the unique ID you get from the database, If you get it.


Example:



const generateKey = (pre) => {
return `${ pre }_${ new Date().getTime() }`;
}

const savedLists = this.state.savedLists.map( list => {
const list_data = list.data.map( data => <li key={ generateKey(data) }>{ data }</li> );
return(
<div key={ generateKey(list.name) }>
<h2>{ list.name }</h2>
<ul>
{ list_data }
</ul>
</div>
)
});





share|improve this answer



















  • 24




    This is fine if the elements do not get removed or added to them but if they do then you will have weird side-effects as React will associate the keys with wrong components
    – Martin Dawson
    Oct 10 '16 at 18:58










  • True., I am sure users can download other libs or create helper functions to take care of this., I will update the answer in regards to this.
    – Random User
    Sep 1 '17 at 6:25










  • Just check out this article: codeburst.io/…
    – Karlen Kishmiryan
    Apr 10 at 10:34


















up vote
7
down vote













One can use uuid npm package for it.



Nodejs common module



const uuidv1 = require('uuid/v1');
uuidv1(); // '10ba038e-48da-487b-96e8-8d3b99b6d18a


With ecma6:



import uuidv1 from  'uuid/v1';
uuidv1(); // '10ba038e-48da-487b-96e8-8d3b99b6d18a





share|improve this answer























  • Dont ever use dynamically generated ID's for React keys. That defeats the purpose of the key management if the component is dynamically rendered, because it breaks the whole tree.
    – Frondor
    Dec 6 at 13:06


















up vote
1
down vote













Updating the answer with v4 of UUID



npm install uuid
-------------------------------------
const uuidv4 = require('uuid/v4');
uuidv4(); // ⇨ '10ba038e-48da-487b-96e8-8d3b99b6d18a'

or

import uuidv from 'uuid/v4';
uuidv4(); // '10ba038e-48da-487b-96e8-8d3b99b6d18a





share|improve this answer




























    up vote
    1
    down vote













    As mentioned before, using index is an antipattern. The best option I've found so far is:



    1) Import "shortid" from React library:



    import shortid from 'shortid';


    2) Use it in your loop like bellow:



    const controls = ;
    collection.map(item => {
    controls.push(<div className="column" key={`div-${shortid.generate()}`}>{item.text}</div>);
    });


    Hope this helps. I just posted this because it was really hard to find a solution like this.






    share|improve this answer





















    • Documentation for React Keys: reactjs.org/docs/lists-and-keys.html#keys Also, don't forget to run "npm install shortid --save"
      – Daniel Santana
      Nov 14 at 22:59




















    up vote
    -4
    down vote













    I am using this:



    <div key={+new Date() + Math.random()}>





    share|improve this answer





















    • this will not work as the keys are determined at time of render, therefore not deterministic.
      – steviejay
      Oct 13 at 4:15











    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f39549424%2fhow-to-create-unique-keys-for-react-elements%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    5 Answers
    5






    active

    oldest

    votes








    5 Answers
    5






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    20
    down vote



    accepted










    There are many ways in which you can create unique keys, the simplest method is to use the index when iterating arrays.



    Example



        var lists = this.state.lists.map(function(list, index) {
    return(
    <div key={index}>
    <div key={list.name} id={list.name}>
    <h2 key={"header"+list.name}>{list.name}</h2>
    <ListForm update={lst.updateSaved} name={list.name}/>
    </div>
    </div>
    )
    });


    Wherever you're lopping over data, here this.state.lists.map, you can pass second parameter function(list, index) to the callback as well and that will be its index value and it will be unique for all the items in the array.



    And then you can use it like



    <div key={index}>



    You can do the same here as well



        var savedLists = this.state.savedLists.map(function(list, index) {
    var list_data = list.data;
    list_data.map(function(data, index) {
    return (
    <li key={index}>{data}</li>
    )
    });
    return(
    <div key={index}>
    <h2>{list.name}</h2>
    <ul>
    {list_data}
    </ul>
    </div>
    )
    });


    Edit



    However, As pointed by the user Martin Dawson in the comment below, This is not always ideal.



    So whats the solution then?



    Many




    • You can create a function to generate unique keys/ids/numbers/strings and use that

    • You can make use of existing npm packages like uuid, uniqid, etc

    • You can also generate random number like new Date().getTime(); and prefix it with something from the item you're iterating to guarantee its uniqueness

    • Lastly, I recommend using the unique ID you get from the database, If you get it.


    Example:



    const generateKey = (pre) => {
    return `${ pre }_${ new Date().getTime() }`;
    }

    const savedLists = this.state.savedLists.map( list => {
    const list_data = list.data.map( data => <li key={ generateKey(data) }>{ data }</li> );
    return(
    <div key={ generateKey(list.name) }>
    <h2>{ list.name }</h2>
    <ul>
    { list_data }
    </ul>
    </div>
    )
    });





    share|improve this answer



















    • 24




      This is fine if the elements do not get removed or added to them but if they do then you will have weird side-effects as React will associate the keys with wrong components
      – Martin Dawson
      Oct 10 '16 at 18:58










    • True., I am sure users can download other libs or create helper functions to take care of this., I will update the answer in regards to this.
      – Random User
      Sep 1 '17 at 6:25










    • Just check out this article: codeburst.io/…
      – Karlen Kishmiryan
      Apr 10 at 10:34















    up vote
    20
    down vote



    accepted










    There are many ways in which you can create unique keys, the simplest method is to use the index when iterating arrays.



    Example



        var lists = this.state.lists.map(function(list, index) {
    return(
    <div key={index}>
    <div key={list.name} id={list.name}>
    <h2 key={"header"+list.name}>{list.name}</h2>
    <ListForm update={lst.updateSaved} name={list.name}/>
    </div>
    </div>
    )
    });


    Wherever you're lopping over data, here this.state.lists.map, you can pass second parameter function(list, index) to the callback as well and that will be its index value and it will be unique for all the items in the array.



    And then you can use it like



    <div key={index}>



    You can do the same here as well



        var savedLists = this.state.savedLists.map(function(list, index) {
    var list_data = list.data;
    list_data.map(function(data, index) {
    return (
    <li key={index}>{data}</li>
    )
    });
    return(
    <div key={index}>
    <h2>{list.name}</h2>
    <ul>
    {list_data}
    </ul>
    </div>
    )
    });


    Edit



    However, As pointed by the user Martin Dawson in the comment below, This is not always ideal.



    So whats the solution then?



    Many




    • You can create a function to generate unique keys/ids/numbers/strings and use that

    • You can make use of existing npm packages like uuid, uniqid, etc

    • You can also generate random number like new Date().getTime(); and prefix it with something from the item you're iterating to guarantee its uniqueness

    • Lastly, I recommend using the unique ID you get from the database, If you get it.


    Example:



    const generateKey = (pre) => {
    return `${ pre }_${ new Date().getTime() }`;
    }

    const savedLists = this.state.savedLists.map( list => {
    const list_data = list.data.map( data => <li key={ generateKey(data) }>{ data }</li> );
    return(
    <div key={ generateKey(list.name) }>
    <h2>{ list.name }</h2>
    <ul>
    { list_data }
    </ul>
    </div>
    )
    });





    share|improve this answer



















    • 24




      This is fine if the elements do not get removed or added to them but if they do then you will have weird side-effects as React will associate the keys with wrong components
      – Martin Dawson
      Oct 10 '16 at 18:58










    • True., I am sure users can download other libs or create helper functions to take care of this., I will update the answer in regards to this.
      – Random User
      Sep 1 '17 at 6:25










    • Just check out this article: codeburst.io/…
      – Karlen Kishmiryan
      Apr 10 at 10:34













    up vote
    20
    down vote



    accepted







    up vote
    20
    down vote



    accepted






    There are many ways in which you can create unique keys, the simplest method is to use the index when iterating arrays.



    Example



        var lists = this.state.lists.map(function(list, index) {
    return(
    <div key={index}>
    <div key={list.name} id={list.name}>
    <h2 key={"header"+list.name}>{list.name}</h2>
    <ListForm update={lst.updateSaved} name={list.name}/>
    </div>
    </div>
    )
    });


    Wherever you're lopping over data, here this.state.lists.map, you can pass second parameter function(list, index) to the callback as well and that will be its index value and it will be unique for all the items in the array.



    And then you can use it like



    <div key={index}>



    You can do the same here as well



        var savedLists = this.state.savedLists.map(function(list, index) {
    var list_data = list.data;
    list_data.map(function(data, index) {
    return (
    <li key={index}>{data}</li>
    )
    });
    return(
    <div key={index}>
    <h2>{list.name}</h2>
    <ul>
    {list_data}
    </ul>
    </div>
    )
    });


    Edit



    However, As pointed by the user Martin Dawson in the comment below, This is not always ideal.



    So whats the solution then?



    Many




    • You can create a function to generate unique keys/ids/numbers/strings and use that

    • You can make use of existing npm packages like uuid, uniqid, etc

    • You can also generate random number like new Date().getTime(); and prefix it with something from the item you're iterating to guarantee its uniqueness

    • Lastly, I recommend using the unique ID you get from the database, If you get it.


    Example:



    const generateKey = (pre) => {
    return `${ pre }_${ new Date().getTime() }`;
    }

    const savedLists = this.state.savedLists.map( list => {
    const list_data = list.data.map( data => <li key={ generateKey(data) }>{ data }</li> );
    return(
    <div key={ generateKey(list.name) }>
    <h2>{ list.name }</h2>
    <ul>
    { list_data }
    </ul>
    </div>
    )
    });





    share|improve this answer














    There are many ways in which you can create unique keys, the simplest method is to use the index when iterating arrays.



    Example



        var lists = this.state.lists.map(function(list, index) {
    return(
    <div key={index}>
    <div key={list.name} id={list.name}>
    <h2 key={"header"+list.name}>{list.name}</h2>
    <ListForm update={lst.updateSaved} name={list.name}/>
    </div>
    </div>
    )
    });


    Wherever you're lopping over data, here this.state.lists.map, you can pass second parameter function(list, index) to the callback as well and that will be its index value and it will be unique for all the items in the array.



    And then you can use it like



    <div key={index}>



    You can do the same here as well



        var savedLists = this.state.savedLists.map(function(list, index) {
    var list_data = list.data;
    list_data.map(function(data, index) {
    return (
    <li key={index}>{data}</li>
    )
    });
    return(
    <div key={index}>
    <h2>{list.name}</h2>
    <ul>
    {list_data}
    </ul>
    </div>
    )
    });


    Edit



    However, As pointed by the user Martin Dawson in the comment below, This is not always ideal.



    So whats the solution then?



    Many




    • You can create a function to generate unique keys/ids/numbers/strings and use that

    • You can make use of existing npm packages like uuid, uniqid, etc

    • You can also generate random number like new Date().getTime(); and prefix it with something from the item you're iterating to guarantee its uniqueness

    • Lastly, I recommend using the unique ID you get from the database, If you get it.


    Example:



    const generateKey = (pre) => {
    return `${ pre }_${ new Date().getTime() }`;
    }

    const savedLists = this.state.savedLists.map( list => {
    const list_data = list.data.map( data => <li key={ generateKey(data) }>{ data }</li> );
    return(
    <div key={ generateKey(list.name) }>
    <h2>{ list.name }</h2>
    <ul>
    { list_data }
    </ul>
    </div>
    )
    });






    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Nov 13 '17 at 6:16

























    answered Sep 17 '16 at 17:04









    Random User

    3,10462741




    3,10462741








    • 24




      This is fine if the elements do not get removed or added to them but if they do then you will have weird side-effects as React will associate the keys with wrong components
      – Martin Dawson
      Oct 10 '16 at 18:58










    • True., I am sure users can download other libs or create helper functions to take care of this., I will update the answer in regards to this.
      – Random User
      Sep 1 '17 at 6:25










    • Just check out this article: codeburst.io/…
      – Karlen Kishmiryan
      Apr 10 at 10:34














    • 24




      This is fine if the elements do not get removed or added to them but if they do then you will have weird side-effects as React will associate the keys with wrong components
      – Martin Dawson
      Oct 10 '16 at 18:58










    • True., I am sure users can download other libs or create helper functions to take care of this., I will update the answer in regards to this.
      – Random User
      Sep 1 '17 at 6:25










    • Just check out this article: codeburst.io/…
      – Karlen Kishmiryan
      Apr 10 at 10:34








    24




    24




    This is fine if the elements do not get removed or added to them but if they do then you will have weird side-effects as React will associate the keys with wrong components
    – Martin Dawson
    Oct 10 '16 at 18:58




    This is fine if the elements do not get removed or added to them but if they do then you will have weird side-effects as React will associate the keys with wrong components
    – Martin Dawson
    Oct 10 '16 at 18:58












    True., I am sure users can download other libs or create helper functions to take care of this., I will update the answer in regards to this.
    – Random User
    Sep 1 '17 at 6:25




    True., I am sure users can download other libs or create helper functions to take care of this., I will update the answer in regards to this.
    – Random User
    Sep 1 '17 at 6:25












    Just check out this article: codeburst.io/…
    – Karlen Kishmiryan
    Apr 10 at 10:34




    Just check out this article: codeburst.io/…
    – Karlen Kishmiryan
    Apr 10 at 10:34












    up vote
    7
    down vote













    One can use uuid npm package for it.



    Nodejs common module



    const uuidv1 = require('uuid/v1');
    uuidv1(); // '10ba038e-48da-487b-96e8-8d3b99b6d18a


    With ecma6:



    import uuidv1 from  'uuid/v1';
    uuidv1(); // '10ba038e-48da-487b-96e8-8d3b99b6d18a





    share|improve this answer























    • Dont ever use dynamically generated ID's for React keys. That defeats the purpose of the key management if the component is dynamically rendered, because it breaks the whole tree.
      – Frondor
      Dec 6 at 13:06















    up vote
    7
    down vote













    One can use uuid npm package for it.



    Nodejs common module



    const uuidv1 = require('uuid/v1');
    uuidv1(); // '10ba038e-48da-487b-96e8-8d3b99b6d18a


    With ecma6:



    import uuidv1 from  'uuid/v1';
    uuidv1(); // '10ba038e-48da-487b-96e8-8d3b99b6d18a





    share|improve this answer























    • Dont ever use dynamically generated ID's for React keys. That defeats the purpose of the key management if the component is dynamically rendered, because it breaks the whole tree.
      – Frondor
      Dec 6 at 13:06













    up vote
    7
    down vote










    up vote
    7
    down vote









    One can use uuid npm package for it.



    Nodejs common module



    const uuidv1 = require('uuid/v1');
    uuidv1(); // '10ba038e-48da-487b-96e8-8d3b99b6d18a


    With ecma6:



    import uuidv1 from  'uuid/v1';
    uuidv1(); // '10ba038e-48da-487b-96e8-8d3b99b6d18a





    share|improve this answer














    One can use uuid npm package for it.



    Nodejs common module



    const uuidv1 = require('uuid/v1');
    uuidv1(); // '10ba038e-48da-487b-96e8-8d3b99b6d18a


    With ecma6:



    import uuidv1 from  'uuid/v1';
    uuidv1(); // '10ba038e-48da-487b-96e8-8d3b99b6d18a






    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Oct 24 at 17:38

























    answered Jul 19 at 17:08









    RIYAJ KHAN

    10.6k41434




    10.6k41434












    • Dont ever use dynamically generated ID's for React keys. That defeats the purpose of the key management if the component is dynamically rendered, because it breaks the whole tree.
      – Frondor
      Dec 6 at 13:06


















    • Dont ever use dynamically generated ID's for React keys. That defeats the purpose of the key management if the component is dynamically rendered, because it breaks the whole tree.
      – Frondor
      Dec 6 at 13:06
















    Dont ever use dynamically generated ID's for React keys. That defeats the purpose of the key management if the component is dynamically rendered, because it breaks the whole tree.
    – Frondor
    Dec 6 at 13:06




    Dont ever use dynamically generated ID's for React keys. That defeats the purpose of the key management if the component is dynamically rendered, because it breaks the whole tree.
    – Frondor
    Dec 6 at 13:06










    up vote
    1
    down vote













    Updating the answer with v4 of UUID



    npm install uuid
    -------------------------------------
    const uuidv4 = require('uuid/v4');
    uuidv4(); // ⇨ '10ba038e-48da-487b-96e8-8d3b99b6d18a'

    or

    import uuidv from 'uuid/v4';
    uuidv4(); // '10ba038e-48da-487b-96e8-8d3b99b6d18a





    share|improve this answer

























      up vote
      1
      down vote













      Updating the answer with v4 of UUID



      npm install uuid
      -------------------------------------
      const uuidv4 = require('uuid/v4');
      uuidv4(); // ⇨ '10ba038e-48da-487b-96e8-8d3b99b6d18a'

      or

      import uuidv from 'uuid/v4';
      uuidv4(); // '10ba038e-48da-487b-96e8-8d3b99b6d18a





      share|improve this answer























        up vote
        1
        down vote










        up vote
        1
        down vote









        Updating the answer with v4 of UUID



        npm install uuid
        -------------------------------------
        const uuidv4 = require('uuid/v4');
        uuidv4(); // ⇨ '10ba038e-48da-487b-96e8-8d3b99b6d18a'

        or

        import uuidv from 'uuid/v4';
        uuidv4(); // '10ba038e-48da-487b-96e8-8d3b99b6d18a





        share|improve this answer












        Updating the answer with v4 of UUID



        npm install uuid
        -------------------------------------
        const uuidv4 = require('uuid/v4');
        uuidv4(); // ⇨ '10ba038e-48da-487b-96e8-8d3b99b6d18a'

        or

        import uuidv from 'uuid/v4';
        uuidv4(); // '10ba038e-48da-487b-96e8-8d3b99b6d18a






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Oct 24 at 18:24









        Knitesh

        1,2561016




        1,2561016






















            up vote
            1
            down vote













            As mentioned before, using index is an antipattern. The best option I've found so far is:



            1) Import "shortid" from React library:



            import shortid from 'shortid';


            2) Use it in your loop like bellow:



            const controls = ;
            collection.map(item => {
            controls.push(<div className="column" key={`div-${shortid.generate()}`}>{item.text}</div>);
            });


            Hope this helps. I just posted this because it was really hard to find a solution like this.






            share|improve this answer





















            • Documentation for React Keys: reactjs.org/docs/lists-and-keys.html#keys Also, don't forget to run "npm install shortid --save"
              – Daniel Santana
              Nov 14 at 22:59

















            up vote
            1
            down vote













            As mentioned before, using index is an antipattern. The best option I've found so far is:



            1) Import "shortid" from React library:



            import shortid from 'shortid';


            2) Use it in your loop like bellow:



            const controls = ;
            collection.map(item => {
            controls.push(<div className="column" key={`div-${shortid.generate()}`}>{item.text}</div>);
            });


            Hope this helps. I just posted this because it was really hard to find a solution like this.






            share|improve this answer





















            • Documentation for React Keys: reactjs.org/docs/lists-and-keys.html#keys Also, don't forget to run "npm install shortid --save"
              – Daniel Santana
              Nov 14 at 22:59















            up vote
            1
            down vote










            up vote
            1
            down vote









            As mentioned before, using index is an antipattern. The best option I've found so far is:



            1) Import "shortid" from React library:



            import shortid from 'shortid';


            2) Use it in your loop like bellow:



            const controls = ;
            collection.map(item => {
            controls.push(<div className="column" key={`div-${shortid.generate()}`}>{item.text}</div>);
            });


            Hope this helps. I just posted this because it was really hard to find a solution like this.






            share|improve this answer












            As mentioned before, using index is an antipattern. The best option I've found so far is:



            1) Import "shortid" from React library:



            import shortid from 'shortid';


            2) Use it in your loop like bellow:



            const controls = ;
            collection.map(item => {
            controls.push(<div className="column" key={`div-${shortid.generate()}`}>{item.text}</div>);
            });


            Hope this helps. I just posted this because it was really hard to find a solution like this.







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Nov 14 at 22:52









            Daniel Santana

            83310




            83310












            • Documentation for React Keys: reactjs.org/docs/lists-and-keys.html#keys Also, don't forget to run "npm install shortid --save"
              – Daniel Santana
              Nov 14 at 22:59




















            • Documentation for React Keys: reactjs.org/docs/lists-and-keys.html#keys Also, don't forget to run "npm install shortid --save"
              – Daniel Santana
              Nov 14 at 22:59


















            Documentation for React Keys: reactjs.org/docs/lists-and-keys.html#keys Also, don't forget to run "npm install shortid --save"
            – Daniel Santana
            Nov 14 at 22:59






            Documentation for React Keys: reactjs.org/docs/lists-and-keys.html#keys Also, don't forget to run "npm install shortid --save"
            – Daniel Santana
            Nov 14 at 22:59












            up vote
            -4
            down vote













            I am using this:



            <div key={+new Date() + Math.random()}>





            share|improve this answer





















            • this will not work as the keys are determined at time of render, therefore not deterministic.
              – steviejay
              Oct 13 at 4:15















            up vote
            -4
            down vote













            I am using this:



            <div key={+new Date() + Math.random()}>





            share|improve this answer





















            • this will not work as the keys are determined at time of render, therefore not deterministic.
              – steviejay
              Oct 13 at 4:15













            up vote
            -4
            down vote










            up vote
            -4
            down vote









            I am using this:



            <div key={+new Date() + Math.random()}>





            share|improve this answer












            I am using this:



            <div key={+new Date() + Math.random()}>






            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Oct 11 at 13:13









            Tudor Morar

            1,430910




            1,430910












            • this will not work as the keys are determined at time of render, therefore not deterministic.
              – steviejay
              Oct 13 at 4:15


















            • this will not work as the keys are determined at time of render, therefore not deterministic.
              – steviejay
              Oct 13 at 4:15
















            this will not work as the keys are determined at time of render, therefore not deterministic.
            – steviejay
            Oct 13 at 4:15




            this will not work as the keys are determined at time of render, therefore not deterministic.
            – steviejay
            Oct 13 at 4:15


















            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f39549424%2fhow-to-create-unique-keys-for-react-elements%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            How to change which sound is reproduced for terminal bell?

            Can I use Tabulator js library in my java Spring + Thymeleaf project?

            Title Spacing in Bjornstrup Chapter, Removing Chapter Number From Contents