React list & Keys
We can use JavaScript’s map()
method to create a list.
React instance
Use map()
method traverses the array to generate a list of numbers 1 to 5:
constnumbers=[1,2,3,4,5];constlistItems=numbers.map((numbers)=>
<li>{numbers}</li>);ReactDOM.render(<ul>{listItems}</ul>,document.getElementById('example'));
We can reconstruct the above instance into a component that receives array parameters and assigns one for each list element key
otherwise, there will be a warning a key should be provided for list items
which means it needs to be included key
:
React instance
functionNumberList(props){constnumbers=props.numbers;constlistItems=numbers.map((number)=>
<likey={number.toString()}>{number}</li>);return(<ul>{listItems}</ul>);}constnumbers=[1,2,3,4,5];ReactDOM.render(<NumberListnumbers={numbers}/>,document.getElementById('example'));
Keys
Keys
can help when some elements in the DOM are added or deleted React
identify which elements have changed. So you should assign a definite identity to each element in the array.
const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((number) =>
<li key={number.toString()}>
{number}
</li>
);
Of an element key
is preferable that this element has a unique string in the list. Usually, we use the id
as an element key
:
const todoItems = todos.map((todo) =>
<li key={todo.id}>
{todo.text}
</li>
);
When the element is not determined id
can use his serial number index index
as key
:
const todoItems = todos.map((todo, index) =>
// Only used when there is no definite ID
<li key={index}>
{todo.text}
</li>
);
If the list can be reordered, we do not recommend using an index for sorting, as this can cause rendering to become slow.
Extract components with keys
Of the element key
it only makes sense when it is compared to its sibling node.
For example, if you extract a ListItem
components, you should put key
the one saved in the array <ListItem/>
element, not on the ListItem
in the component <li>
on the element.
A false demonstration.
function ListItem(props) {
const value = props.value;
return (
// Wrong! You don't need to specify a key here:
<li key={value.toString()}>
{value}
</li>
);
}
function NumberList(props) {
const numbers = props.numbers;
const listItems = numbers.map((number) =>
//Wrong! The key of the element should be specified here:
<ListItem value={number} />
);
return (
<ul>
{listItems}
</ul>
);
}
const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
<NumberList numbers={numbers} />,
document.getElementById('example')
);
The correct use of key
React instance
functionListItem(props){//By the way! There is no need to specify a key here:
return<li>{props.value}</li>;}functionNumberList(props)
{constnumbers=props.numbers;constlistItems=numbers.map((number)=>
//That's right again! The key should be specified in the context of the array
<ListItemkey={number.toString()}value={number}/>);return(<ul>{listItems}</ul>);}
constnumbers=[1,2,3,4,5];ReactDOM.render(<NumberListnumbers={numbers}/>,
document.getElementById('example'));
When you are in map()
method, you’d better always remember to add a unique key
.
Of the element key
among his brother elements, it should be unique.
Used in array elements key
should be unique among his brothers. However, they do not need to be globally unique. When we generate two different arrays, we can use the same key.
React instance
functionBlog(props){constsidebar=(<ul>{props.posts.map((post)=>
<likey={post.id}>{post.title}</li>)}</ul>);constcontent=props.posts.map((post)=>
<divkey={post.id}> <h3>{post.title}</h3> <p>{post.content}</p>
</div>);return(<div>{sidebar}<hr/>{content}</div>);}constposts=[{id:1,title:'Hello
World',content:'Welcome to learning
React!'},{id:2,title:'Installation',content:'You can install React from
npm.'}];ReactDOM.render(<Blogposts={posts}/>,document.getElementById('example'));
key
will serve as a hint to React, but will not be passed on to your components. If you need to use and key
the same value, pass it as an attribute:
const content = posts.map((post) =>
<Post
key={post.id}
id={post.id}
title={post.title} />
);
In the above example, the Post component can read props.id
, but cannot be read out props.key
.
Embed in jsx map()
In the above example, we declare a separate listItems
variable and include it in the JSX:
function NumberList(props) {
const numbers = props.numbers;
const listItems = numbers.map((number) =>
<ListItem key={number.toString()}
value={number} />
);
return (
<ul>
{listItems}
</ul>
);
}
JSX allows you to embed any expression in curly braces, so we can use the map()
is used in the following ways:
React instance
functionNumberList(props){constnumbers=props.numbers;return(<ul>{numbers.map((number)=>
<ListItemkey={number.toString()}value={number}/>)}</ul>);}
Doing so can sometimes make your code clearer, but sometimes this style can be abused. As in JavaScript, when you need to extract a variable for readability is entirely up to you. But remember, if a map()
with too many levels of nesting, you can extract the components.