In React, when rendering a mapping from elements of a list/array/iterable to React elements, we're required to attach a locally-unique key to each element. Generally this is 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, and if an element-specific key is not forthcoming, there is an npm package* (shortid) for generating them.
Why did the React designers set this requirement rather than allowing any immutable value? In particular, it makes sense to me to be able to use a Symbol
, which cannot be converted to a unique string. (Upon re-examining my specific case where I wanted to use a Symbol
, I realized it was unnecessary, but the question still stands in general.)
* There also used to be a package specifically designed for this called react-key-index
but it seems to have disappeared from github.
2 Answers 2
React writes the key to the HTML and reads it back when parsing the DOM.
Since the HTML attribute is a string, whatever value you give it must be serialised to a string.
If you wanted to use non strings you would require a de/serialiser and possibly a second attribute in the HTML element to indicate the type of the key value.
Also remember this is essentially an optimisation so we don't have to re generate the entire HTML on every change. So anything that would slow the process down would be undesirable.
-
1This might have been true in the past, but if you inspect the element tree in your browser, you'll see that no such attribute gets written to the HTML.thebearingedge– thebearingedge2021年10月21日 20:23:42 +00:00Commented Oct 21, 2021 at 20:23
-
jeeze 2018 seems so long ago. maybe i was just wrong? you should add a new answerEwan– Ewan2021年10月22日 16:43:32 +00:00Commented Oct 22, 2021 at 16:43
-
excellent suggestionthebearingedge– thebearingedge2021年10月22日 20:30:36 +00:00Commented Oct 22, 2021 at 20:30
Up-to-date as of 2021
They're not, but the React docs encourage the use of strings over any other type. Any data type will "work" (except undefined
as @theHutt points out).
This is because React coerces your key into a string before storing it for future reconciliations. It does so with a simple concatenation (essentially key = '' + key
).
The sanest type to concatenate like this is another string. So long as, in the case of an array of React elements, the resulting string is unique amongst the elements, it'll work.
Here's a link to the source code.
-
1
undefined
doesn't workthe Hutt– the Hutt2022年05月02日 14:38:18 +00:00Commented May 2, 2022 at 14:38 -
@theHutt Good catch!thebearingedge– thebearingedge2022年05月03日 15:28:39 +00:00Commented May 3, 2022 at 15:28
key="Foo"
andkey={Symbol('Foo')}
could represent different items.