This question already has answers here:
How to create unique keys for React elements?
(16 answers)
Closed 3 years ago.
How can I generate custom IDs for input without using any packages/moduls outside of React?
I found this example for unique keys using index, but as one user pointed out, while React documentation says you can do it that way:
const todoItems = todos.map((todo, index) =>
// Only do this if items have no stable IDs
<li key={index}>
{todo.text}
</li>
);
It's not wise to use index for this. Is there any other way I could generate unique IDs with React? Thanks!
In the react docs you link it's says: "We don’t recommend using indexes for keys if the order of items may change."
So if you change the orders in your array (like sorting them) and you haven't a unique propertie just give them one initial (when you create the array or directly after getting the array)
todos.forEach((todo, index) => todo.index = index);
Related
This question already has answers here:
How can I use optional chaining with arrays and functions?
(6 answers)
Closed 3 months ago.
I fetched data from an API and I get this :
An array of arrays containing objects and properties containing the details of songs.
The issue is when i try to access the uri property, I get "Cannot read properties of undefined (reading '1')" with the code below :
const songTitleEl = chartData.map(data =>(
<ChartSongs key={data.key} audio={data?.hub?.actions[1]?.uri}/>
))
It should be working perfectly but it isn't and for the life of me I can't figure why.
actions could be null. Need the ? to check if index exists
<ChartSongs key={data.key} audio={data?.hub?.actions?.[1]?.uri}/>
React Doc explains why giving a key to list item is important. It specifies that a key is string attribute.
So should I convert my id to string for key every time?
<ul>
{data.map(item => (
<li key={item.id.toString()}>
{item.text}
</li>
</ul>
Could you tell me the reason for this? I thought about problem with number sort as strings but it seemed to be another case.
React Doc. List and Keys
Key is fundamental for the React to index a list in the render process (in the background). If you don't put the key, you get this:
This simply means that he needs to look for the component, what will take longer.
To solve the toString(), to this:
key={`OperationTesterInput_${idx}`
Looks much more cleaner. You can also use the index parameter present in the map function, also does the trick :)
The Reason why its a string
It is not. The reason is because of typescript. The implementation is the following:
So following this implementation, this is valid:
Generally, Key is used so that if an element changes or is removed, React only needs to rerender that specific element rather than the whole list. This key is required to be a string because the HTML attribute values are always strings, whatever value you give must be serialized to a string. We can assign anything to an attribute, but it becomes a string.
This question already has answers here:
Check if every element in one array is in a second array
(10 answers)
Closed 2 years ago.
I am trying to filter my entites by tags array, that can look like this:
const tags = ["tag1", "tag2"];
Every entity has property tags, that can have existing tags, for example:
["tag1", "tag2", "tag3"];
Or:
["tag1", "tag2"];
I need to compare if the tags array and the tags array of entity has the same values.
So far I have tried this code, but it returns an entity even if the two arrays dont have the same values (I'm guessing the includes() function is to blame).
tags.every((tag: any) => doc.tags.includes(tag));
Any ideas how can I check if the arrays have the same values?
Thank you in advance.
You can also compare the length as well
tags.every((tag: any) => doc.tags.includes(tag)) && tags.length === doc.tags.length;
This question already has answers here:
Understanding unique keys for array children in React.js
(27 answers)
Closed 2 years ago.
I know that we need a key to know which element from the list has been deleted or modified. But how does "key" exactly work? What happens "under the hood" in React if we miss a "key" attribute?
If keys are not added, React has to iterate over the entire list if you have inserted an element at the beginning. Since it
doesn't know what else has changed.
For example, converting between these two trees works poorly:
<ul>
<li>Duke</li>
<li>Villanova</li>
</ul>
<ul>
<li>Connecticut</li>
<li>Duke</li>
<li>Villanova</li>
</ul>
React will mutate every child instead of realizing it can keep the <li>Duke</li> and <li>Villanova</li> subtrees intact.
Note that if item is inserted at end, React optimizes this and O(n) comparisons may not be made.
There are other potential dangers of using indexes as keys. See why this is an anti-pattern
React requires that you have a unique key attribute on elements in an array. The React docs recommend using an id from your data. If you don't have an id then you can use the array index as a "last resort", with the caveat that using an index can cause performance issues when the items can be re-ordered. I've also had some annoying issues when building an array of elements from multiple source arrays and multiple calls to .map(), each with different transformations, in which case the array indexes won't be unique anyways.
I've started throwing the following boilerplate into my components:
constructor(props) {
super(props);
this.getId = this.getId.bind(this);
this.id = 0;
}
getId() {
return this.id++;
}
which can be used like so:
render() {
const items = this.props.greetings.map(text => ({
<li key={this.getId()}>{text}</li>
}));
return (
<ul>
{items}
</ul>
);
}
This is simple, fast, and doesn't have the issues that using the array index has, but I don't know if there are any issue with this approach or better alternatives that I'm overlooking. Is this bad practice? Are there any other simple ways of generating keys that don't have the array index issues?
This is what the docs on Reconciliation have to say on keys
In practice, finding a key is usually not hard. The element you are going to display may already have a unique ID, so the key can just come from your data.
When that’s not the case, you can add a new ID property to your model or hash some parts of the content to generate a key. The key only has to be unique among its siblings, not globally unique.
As a last resort, you can pass item’s index in the array as a key. This can work well if the items are never reordered, but reorders will be slow.
So I think you are following the suggested approach.