How to access the "key" property from a reactjs component - reactjs

How can I access the key property of a component. I thought it would be in this.props but it's not.
e.g.
<ProductList
key = {list.id}
listId = {list.id}
name = {list.name}
items = {list.items}
/>
and in product list if I do
console.log(this.props)
returns
Object {listId: "list1", name: "Default", items: Array[2]}
With no key property at all. I can create another property and assign the same value to it, but it seems redundant since the key property is already being used.
Also, does the key property have to be unique in the entire component, or just in the loop or collection it's being rendered from?

The key property is used by React under the hood, and is not exposed to you. You'll want to use a custom property and pass that data in. I recommend a semantically meaningful property name; key is only to help identify a DOM node during reconciliation, so having another property called listId makes sense.
The key property does not need to be unique for the whole component, but I believe it should be unique for the nesting level you're in (so generally the loop or collection). If React detects a problem with duplicate keys (in the development build), it will throw an error:
Warning: flattenChildren(...): Encountered two children with the same key, .$a. Child keys must be unique; when two children share a key, only the first child will be used.

Key : this._reactInternalFiber.key
Index : this._reactInternalFiber.index

Related

Is it possible to use the mapped key value in react somehow? [duplicate]

How can I access the key property of a component. I thought it would be in this.props but it's not.
e.g.
<ProductList
key = {list.id}
listId = {list.id}
name = {list.name}
items = {list.items}
/>
and in product list if I do
console.log(this.props)
returns
Object {listId: "list1", name: "Default", items: Array[2]}
With no key property at all. I can create another property and assign the same value to it, but it seems redundant since the key property is already being used.
Also, does the key property have to be unique in the entire component, or just in the loop or collection it's being rendered from?
The key property is used by React under the hood, and is not exposed to you. You'll want to use a custom property and pass that data in. I recommend a semantically meaningful property name; key is only to help identify a DOM node during reconciliation, so having another property called listId makes sense.
The key property does not need to be unique for the whole component, but I believe it should be unique for the nesting level you're in (so generally the loop or collection). If React detects a problem with duplicate keys (in the development build), it will throw an error:
Warning: flattenChildren(...): Encountered two children with the same key, .$a. Child keys must be unique; when two children share a key, only the first child will be used.
Key : this._reactInternalFiber.key
Index : this._reactInternalFiber.index

why do I get "`key` is not a prop." in React?

So I have the code below, with bookList_object being a bunch of JSON objects I fetched from backend.
_renderBookList = () => {
const books = this.state.bookList_object.map((this_book, index) => {
return <BookList
body={this_book.body}
created_at={this_book.created_at}
key = {index}
/>
})
Now, I've learned that there has to be key when having multiple children. So I've used index parameter to assign each id to the key prop. But then I get this error:
"BookList: key is not a prop. Trying to access it will result in undefined being returned. If you need to access the same value within the child component, you should pass it as a different prop."
What have I done wrong?
Also, I already have id field in each of my object. Is there a way to use id instead of key?
Thank you very much in advance. :)
I recently had this Warning. It happened because I tried to assign a key to some elements in two different parts of the code. The warning pops up when the key prop is accessed a second time.
Find out where else the component is being assigned a key. Then choose only one place to assign a key.

React: Siblings in a list must have unique key. Do the children of these list siblings need them too?

I am generating a series of divs by using .map() on my state (created via the useState() React hook).
Each of these divs has a unique React key. However, I still receive the following error:
Warning: Each child in a list should have a unique "key" prop.
Each of these <div> siblings has 30-50 children. Does each of those children need a unique React key as well?
The React documentation (https://reactjs.org/docs/lists-and-keys.html) appears ambiguous on this point.
It indicates that:
"A good rule of thumb is that elements inside the map() call need keys." (All elements? Or just the parent siblings?)
Keys must only be unique among siblings. (The scenario I describe follows this rule)
However none of its examples provide clarity on list siblings with many nested elements within.
Thanks in advance for your help.
every time when you are rendering any series of nodes(React.Fragment, div, span etc) in loop like bellow you must have to do:
const list = [...list of your raw items]; // Array<{id: number, name: string}>
return (
<main>
{list.map((item, index) => (
<section key={item.id}>
<div><span>{item.name}</span></div>
</div>
))}
</div>
)
define key for top-level node element inside map callback(in my example it is section);
key should be an uniq parameter within current loop, it can be index but it is not recommended(for better performance in case if you dynamically modify list). Usually it is an ID of each entity;
ps. You do not have to pass down key for any children(in my example - div and span), but it is not harmful tho(just useless).

trying to acces the key property passed to other component, but in the component it is passed [duplicate]

How can I access the key property of a component. I thought it would be in this.props but it's not.
e.g.
<ProductList
key = {list.id}
listId = {list.id}
name = {list.name}
items = {list.items}
/>
and in product list if I do
console.log(this.props)
returns
Object {listId: "list1", name: "Default", items: Array[2]}
With no key property at all. I can create another property and assign the same value to it, but it seems redundant since the key property is already being used.
Also, does the key property have to be unique in the entire component, or just in the loop or collection it's being rendered from?
The key property is used by React under the hood, and is not exposed to you. You'll want to use a custom property and pass that data in. I recommend a semantically meaningful property name; key is only to help identify a DOM node during reconciliation, so having another property called listId makes sense.
The key property does not need to be unique for the whole component, but I believe it should be unique for the nesting level you're in (so generally the loop or collection). If React detects a problem with duplicate keys (in the development build), it will throw an error:
Warning: flattenChildren(...): Encountered two children with the same key, .$a. Child keys must be unique; when two children share a key, only the first child will be used.
Key : this._reactInternalFiber.key
Index : this._reactInternalFiber.index

Using object instance as a key in React list

I have a list of objects which I want to render as a list using React.
React requires the special key attribute on the list element in order to track changes between DOM and virtual DOM.
My object doesn't have any special unique properties like id, in fact, two objects could even have the same properties, but the object itself is unique.
Is there a way to use object's reference as a key to render React list?
Otherwise, what workarounds could be suggested in this case?
Also, I'm receiving the list of items from a third party, so I can't just attach a random ID to each item, because it will make the React to re-render all items each time I receive updated data.
If you don't have a unique ID (returned by the back-end, or you can't build a composite key on the front-end), then you can use the array index as key:
render() {
return array.map((item, index) => <Item key={index} />)
}
Without having an unique ID, whatever approach you choose, if the order of the items is changed, then the list can get totally messed up.
It would be safe enough to use this approach if your case met the following 3 conditions, thanks to this article:
the list and items are static–they are not computed and do not change.
the items in the list have no ids.
the list is never reordered or filtered.
Using array's index as a key would be a disaster, because if array changes, the view will not be properly updated or will be updated partially in an unpredictable manner.
The only solution I've found is to generate the dummy IDs as suggested in the comments.
The idea is to implement the generator, which will create an ID for each item, but at the same time will remember previously generated IDs.
The WeakMap JavaScript class will allow us to store the mapping information between the item object reference and generated ID:
export class IdGenerator {
// Using WeakMap as index
map = new WeakMap();
// Internal counter
lastId = 0;
getItemId(item) {
// Getting previously generated ID for the specified item
let id = this.map.get(item);
// If item is new, generating the ID and storing it for future use
if (undefined === id) {
id = ++(this.lastId);
this.map.set(item, id);
}
// Returning ID to the caller in either case
return id;
}
}
Then it could be used to assign generated IDs to each item before rendering the list:
class ListBox extends Component {
// Instantiating the generator
itemsIdGenerator = new IdGenerator();
render() {
return (
<ul>
{this.props.items.map(item => (
<li key={this.itemsIdGenerator.getItemId(item)}>
{item.title}
</li>
))}
</ul>
);
}
}
Make sure to use different instance of the generator for each instance of the component though and create generator only once with the component.
Also, calling the generator for each item in component's render method could be sub-optimal. However, I didn't want to touch the original items or mutate them. If this is an issue, consider using various lifecycle methods provided by React to set IDs when props changes.

Resources