-
Notifications
You must be signed in to change notification settings - Fork 46.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow suppressing the warning for missing keys. #14374
Comments
In that case why not just add the index as the Explicitly using the With an explicit
What would be your proposed API for suppressing the warning? There's precedence with the |
The semantics aren’t an implementation detail. The semantics are “If no key is specified, identity is defined by the order of the elements”, which is exactly the same as “…by the index into the array of elements”. Also the docs explicitly say “If you choose not to assign an explicit key to list items then React will default to using indexes as keys” which can therefore be considered stable behavior. I think
Apologies – I meant the content of blog posts, if you e.g. convert markdown to a virtual DOM tree. Then you can e.g. use React to make the posts morph into each other via CSS transitions, but of course the posts are completely independent and similarities only arise through the structure (e.g. almost all of them start with a title and then paragraphs) |
Sorry, I missed that part. That would be considered stable behavior, though it's still implicit and the docs also state:
Which implies that you should be explicitly using the index in those cases. We probably need to fix the documentation, because the messaging is somewhat confusing here.
Silencing the warning on the parent is problematic as you can have multiple lists with different key requirements. <div suppressKeyWarning>
{/* No keys required here... */}
{[<div>first</div>]}
{/* But keys are required here, and the warning was suppressed! */}
{this.state.items.map(item => <div>{item}</div>}
</div>
It's less data than adding a key to every item in the array separately, like this example. In most cases you'd be mapping through a set of items <parent>{items.map(data => <item {...data} />}</parent> In which case you'd be declaring the key once in the source <parent>{items.map((data, i) => <item key={i} {...data} />}</parent> If you have a static list of items where you are explicitly adding |
And this is how I understand it, but I would prefer to use the simplest possible code for the simplest possible case. Why do something manually, noising up my code, if it’s done automatically anyway?
You’re right. Thinking of it, the property “keys are not needed” pertains to the array. So maybe it should be a function that adds a custom property to an array that marks it as identity safe? <div>
{/* No keys necessary */}
{React.suppressKeyWarning([<div>first</div>])}
{/* Warning thrown here */}
{this.state.items.map(item => <div>{item}</div>}
</div> Of course it could also be named
Exactly. And my code gets a bit more complex (I now have to use and pass on the index), and every item ends up with a useless key property that I’ll see in the debugger. That’s what I meant with data. |
This seems like it is already supported with the current React API: render(
<ul>
{React.Children.toArray([1, 2, 3].map(item => <li>{item}</li>))}
</ul>
);
|
Thank you! If it doesn’t do too much unnecessary work and impacts performance, that’s almost what we’re searching for. Of course not actually adding the keys but simply marking the array as “no keys necessary” would be better for performance. If there’s no performance hit and this information would end up being referenced in the keys section of the docs, I’d be happy. |
@hamlim @flying-sheep we've discussed this before and concluded that
For the reasons mentioned above, I think relying on implicit keys is actually more complex than explicitly using keys because it relies on behavior that isn't obvious.
I would argue that a new API like |
Interesting, should the docs be updated to not mention the fact that the elements in toArray get assigned keys since it should be considered an implementation detail and not necessary "stable" for this use case? |
I was going to post this on #2816, but I noticed this open issue, so, here it goes... What if we use a structure like: import React from 'react'
const myData = [
Something,
Or,
Whatever
]
const ListItems =({ items }) => Object.freeze(
items.map(
item => <li>{item}</li>
)
)
const List = () => <ul><ListItems items={myData} /></ul> In my head,
By |
Technically you can always do what JSX does — Of course it's error-prone if children are dynamic so we don't advertise this. |
So basically const StaticList = (...children) => React.createElement(React.Fragment, {}, ...children) |
For those interested, a solution that worked for me is posted here: resend/react-email#1150 (comment) |
There are valid use cases for not wanting to use keys, if you e.g. render strongly differing trees (like e.g. blog posts) or have a function that returns always the same array of items.
When you don’t provide an explicit key, React will internally use the index as key and emit a warning – however you would want to silence the warning, as using the index here is perfectly valid.
This doesn’t currently seem to be possible however, which has the sad consequence that you either have to make your code more complex for no reason (manually adding useless keys) or you have to live with the warnings (which means that valid warnings might be lost among the noise).
The article quoted in the docs states the conditions in which using the default behavior is valid:
The text was updated successfully, but these errors were encountered: