In which case react key prop warning can be ignored - reactjs

A common pattern is generating react elements from array. In case of iterating over react components are there any cases where should/can ignore key prop warning?
Like can we ignore in case of element rendering static text etc?
Note: After rendering my elements aren't going to change, add new or remove.
const days = ['Sunday' 'Mon.........,,, 'Saturday'];
days.map(day => <div>{day}</div>);

You shouldn't be ignoring this warning.
Have a read of the doc: https://reactjs.org/docs/lists-and-keys.html#keys
Keys help React identify which items have changed, are added, or are removed. Keys should be given to the elements inside the array to give the elements a stable identity
If you truely don't have any key like value to use, you can use the index of the array (assuming its coming from a statically ordered source) so that react can use the keys to identity what has changed.
const myArray = ["Some", "Static", "Stuff"]
const MyComponent = () => (
<div>
{myArray.map((item, i) => <div key={i}>{item}</div>)}
</div>
)

Related

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).

Each child in an array or iterator should have a unique "key" prop. Not sure why

const list = props.things.toDo.map(
function(thing) {
return(
<li>{thing.name}</li>
);
}
);
Cant figure this out keep getting this react warning?!
Keys help React identify which items have changed, are added, or are removed. Keys should be given to the elements inside the array to give the elements a stable identity:
const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((number) =>
<li key={number.toString()}>
{number}
</li>
);
The best way to pick a key is to use a string that uniquely identifies a list item among its siblings. Most often you would use IDs from your data as keys:
const list = props.things.toDo.map(
function(thing) {
return(
<li key={thing.id}>{thing.name}</li>
);
}
);
When you don’t have stable IDs for rendered items, you may use the item index as a key as a last resort:
const list = props.things.toDo.map(
function(thing, index) {
return(
<li key={index}>{thing.name}</li>
);
}
);
We don’t recommend using indexes for keys if the order of items may change. This can negatively impact performance and may cause issues with component state. If you choose not to assign an explicit key to list items then React will default to using indexes as keys.
Reference: https://reactjs.org/docs/lists-and-keys.html#keys
As a quick fix, try this:
<li key={thing.name}>{thing.name}</li>
Then read up on the React docs for Lists and Keys.
Keys help React identify which items have changed, are added, or are removed. Keys should be given to the elements inside the array to give the elements a stable identity.
You'll probably want to replace the key with a truly unique value, if thing.name is not guaranteed to be the same across items.
const list = props.things.toDo.map((x, i) => <li key={i}>{thing.name}</li>);
Your code can be condensed down to the above code instead. As other has mentioned, whenever we rendering a list, React will need each and every individual element to be unique which in that case it needs a key prop, but instead of using key={thing.name} which I believe there is a chance that thing.name is not unique, I would normally use index instead which is 100% guaranteed to be unique

React state array updates/renders entire array, is there a work-around?

Here's the basic idea...
constructor(props) {
super(props);
this.state = {
children: [{id:1},{id:2}], // HERE ARE THE TWO OBJECTS
style: {top: 0}
};
}
Now let's say I update one of those two objects but those objects are mapped to an array of components.
<div className="thread">
{this.state.children.map((child) =>
<Post
key={child.id}
id={child.id}
/>
)}
</div>
Now... when I update one of those objects...
changeID (id, newID) { // this is a different function, just an example
let temp = this.state.children;
for (let i = 0; i < temp.length; i++) {
if (temp[i].id === id) {
temp[i].id = newID; // <- update this
}
}
this.setState({
children: temp // <- plug temp[] back as the updated state
});
}
I throw the new state back in, but it updates each of the mapped objects.
// on one change to one element
id 1 POST UPDATED
id 2 POST UPDATED
1) Does it re-render EVERY component (in the mapped array) or is it smart enough to tell that the state values passed as props to the mapped component are the same?
2) Is it incredibly expensive in processing power if that array is significantly longer?
3) If yes, how can I go about this better? Constructive criticism is appreciated.
Thank you!
This is how react works, whenever you change any state variable it will re-render the complete component and update the virtual dom not the actual dom, then it will check the diff between these two and change only that particular element in actual dom.
As per DOC:
React provides a declarative API so that you don't have to worry about
exactly what changes on every update.
React Only Updates What's Necessary:
React DOM compares the element and its children to the previous one,
and only applies the DOM updates necessary to bring the DOM to the
desired state.
DOM Elements Of The Same Type:
When comparing two React DOM elements of the same type, React looks at
the attributes of both, keeps the same underlying DOM node, and only
updates the changed attributes.
For Example:
<div className="before" title="stuff" />
<div className="after" title="stuff" />
By comparing these two elements, React knows to only modify the className on the underlying DOM node.
Use of Keys:
React supports a key attribute. When children have keys, React uses
the key to match children in the original tree with children in the
subsequent tree.
Imp:
Keys help React identify which items have changed, are added, or are
removed. Keys should be given to the elements inside the array to give
the elements a stable identity. Keys used within arrays should be unique among their siblings. However they don't need to be globally unique.
For example:
<ul>
<li key="2015">Duke</li>
<li key="2016">Villanova</li>
</ul>
<ul>
<li key="2014">Connecticut</li>
<li key="2015">Duke</li>
<li key="2016">Villanova</li>
</ul>
Now React knows that the element with key '2014' is the new one, and the elements with the keys '2015' and '2016' have just moved.
Check this article: How Virtual-DOM and diffing works in React

Are item keys required when rendering an array in React v15?

In earlier versions of React, I remember getting a warning when rendering an array without specifying a unique key for every item:
render() {
return (
<div>
{this.props.items.map(item => <span>{item.text}</span>)}
</div>
);
}
I understand that it is recommended to specify keys when rendering a dynamic list of items (where items can be added or removed) to help the reconciliation algorithm. I'd like to understand:
Why React doesn't warn anymore when keys are missing?
For static lists, is there a value in specifying item keys?
Official pointers will be appreciated.
Actually, I still see this warning message, and in official release notes there is no mention about this case
Example

Resources