From what I can tell, I'm using key
correctly and on the right component but the error persists despite my efforts.
I have a Notifications
component that renders a list of single Notification
components via array.map(). Normally this works out fine when the text for the notification is a string, but when it's JSX (like a p
with a link) I keep getting the "child elements must have a unique key" warning. In this case, there is only a single notification so the key is unique.
This is the code that sets the notification in Redux:
props.setNotification({
type: 'error',
domain: 'page/section',
text: (
<p>
An error occurred.{' '}
<a href="/somewhere/else">Learn more</a>
</p>
)
})
The notifications component reads Redux and loops over the appropriate notifications:
export const Notifications = ({ notifications, type, domain }) =>
notifications
.filter(
note =>
(!type && !domain) ||
(domain && note.domain === domain) ||
(type && note.type === type),
)
.map((note, i) => (
<Notification key={`note_${i}`} note={note} />
)
And finally, the single notification component is just basic JSX (these components are StyledComponents):
const Notification = ({ className, note }) => (
<Notification type={note.type} className={className}>
<Icon name={typeIconMap[note.type]} size="18" />
<Text>{note.text}</Text>
</Notification>
)
The warning says:
index.js:2178 Warning: Each child in a list should have a unique "key" prop. See docs for more information.
in p
in div (created by Text)
in Text (created by Notifications)
in div (created by Notification)
in Notification (created by Notifications)
in Notifications (at Notifications/index.js:15)
in Notifications (created by Connect(Notifications))
So far I've tried:
- adding a key to the paragraph created in
setNotification
, but it didn't do anything despite the warning pointing to that element first. - using different elements instead of
p
, likeReact.Fragment
, but that changed nothing, even if those elements had static keys themselves. - passing
key
into the Notification component, but that caused another error because you can't pass/accesskey
in children. - changing the key that gets assigned in
Notifications
to something more stable than{i}
. I tried{btoa(note.text)}
and some other variations but nothing worked. Given that it works iftext
is just a string, and it even works when using a singleNotification
directly (manually giving it anote
object instead of usingNotifications
, even with JSX as thetext
) I don't understand why this specific case would throw the error.
Is there anything obvious I'm missing here. Why does this work when text
is a plain string, but not when it's JSX.