This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-10-05
Channels
- # announcements (2)
- # babashka (9)
- # bangalore-clj (4)
- # beginners (20)
- # calva (5)
- # cider (1)
- # clara (2)
- # clojure (11)
- # clojure-italy (2)
- # clojure-spec (11)
- # clojure-uk (4)
- # clojurescript (34)
- # clojutre (7)
- # code-reviews (5)
- # cursive (3)
- # datascript (7)
- # fulcro (7)
- # graalvm (8)
- # jackdaw (1)
- # malli (1)
- # nrepl (4)
- # off-topic (225)
- # reagent (23)
- # reitit (14)
- # remote-jobs (1)
- # ring-swagger (1)
- # shadow-cljs (19)
- # tools-deps (10)
noob q: I'm rendering some table data, and I'm getting a lot of these warnings in my js console: Warning: Every element in a seq should have a unique :key:
seems like React itself is also warning of something similar/the same: Warning: Each child in a list should have a unique "key" prop
I have zero experience with React, and minimal cljs experience. Old programmer though. I guess I'm just looking for some basic conceptual understanding of the issue/problem.
tl;dr: Provide a unique :key
metadata value for each child in a lazy collection of children. The value should meaningfully identify a child.
thanks. It looks like in some examples, they're just using a forever-incrementing number in an atom as a cheap way to produce a unique id. This wouldn't really "meaningfully identify" a child though would it?
So, would doing this (incrementing numeric technique) make the warning go away, but suffer some performance hit for React?
Attaching a nonsensical key would result in strange absence of children updates. At least, that's my experience.
Using just (range)
may be fine but only if the values end up in the children as well.
E.g. like in this React example:
const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((number) =>
<li key={number.toString()}>
{number}
</li>
);
Note that in Reagent, you don't have to convert a :key
to string explicitly.This is the relevant section from the React documentation that goes into detail on why using indices as keys may be a bad idea: https://reactjs.org/docs/lists-and-keys.html#keys
One observation - this "key" information does not appear to make it out to the "actual DOM" (according to my web inspector), so I presume React only uses this internally, I guess in its shadow DOM.
I've done web SPAs for a long time, and we leak out all kinds of noise and attributes to the actual DOM. So I'm still adjusting to the Reagent/React way of things.
(adjusting in this case means: "ok, I added the key stuff, and the warnings stopped, but how come I don't see my key attributes in the domm OHHHHHHHH riiiiiiight React.....)
yeah, the React link explains the reasoning: when you have a dynamic list of items, in the worst case React has to re-render and re-commit the entire list.
by adding keys, if they’re meaningful, React can intelligently remove, add or update only the changed children when it re-renders the parent
which is why using the index of a collection isn’t a good idea: if you remove something from the middle, everyone’s key changes, so React has to re-render and re-commit them because it can’t tell if they’re new or old
Also, consider installing React Developer Tools addon for your browser. It will display much more information that more closely resembles what you send to the render function.
Great info, thank you both. In my case I do have a meaningful key in the form of a timestamp (inst). I gave the inst directly as the key. Is it ok to give "objects" like this from clojure, or is it better to explicitly give it a string? Or does it not matter? Does reagent just "toString" it? I can't imagine React would be able to do meaningful things with cljs objects that aren't strings. ..?