As announced by Josh Comeau on twitter today, React in a future version (v16.4.0 maybe?) will have a new utility hook called useOpaqueIdentifier
:
๐ React is getting a new hook,
โ ๐ซ Josh (@JoshWComeau) April 16, 2020useOpaqueIdentifier
, which can be used to generate unique IDs (to be used for form labels, aria-labelledby, etc), in an SSR-safe way.
Exciting!https://t.co/UyJtle6IhY
I've always needed a safe function like this in React to auto-generate the id
of a input field so that I can associate it with a <label>
's for
attribute for accessibility and usability purposes. We could use a global running counter or worse, just a random number, but with server-side rendering there was never a guarantee that the ID generated server-side would be the same when the app hydrated client-side. If there is an ID mismatch, then the UI would have to re-render.
So in theory, when the feature is stable, we would use useOpaqueIdentifier
like so:
import React, { useOpaqueIdentifier } from 'react'
const TextField = ({ value, onChange, label }) => {
const id = useOpaqueIdentifier()
return (
<div className="text-field__root">
<label htmlFor={id}>{label}</label>
<input type="text" id={id} value={value} onChange={onChange} />
</div>
)
}
export default TextField
Until the feature is stable, it'll be accessible via unstable_useOpaqueIdentifier
on the experimental releases of react
:
import React, { unstable_useOpaqueIdentifier } from 'react'
The same hook could be used to generate an ID to associate a non-<label />
with an input using aria-labeledby
.
I was wondering what the "opaque" part in the name is supposed to signify. The hook was originally named useUniqueId
, which is basically how it's mainly going to be used. So I asked about it:
I don't under the "opaque" in the name. Read through the PR comments and it looks like @sebmarkbage suggested it?
โ Ben Ilegbodu ๐ (@benmvp) April 17, 2020
And of course Twitter came to the rescue:
I guess the naming is a nod to opaque types in OCaml or Flow. In those languages, values of an opaque type can only be created within the module that declares the type. Outside of that module, these values can be passed around but you can only make limited assumptions about them.
โ Marius Schulz (@mariusschulz) April 17, 2020
My intuition is that
โ Brandon Dail (@aweary) April 17, 2020opaque
is meant to imply that you shouldn't have any assumptions about the value. Don't assume it's a specific type of value like string or number, consider it a black box.
I still feel that useOpaqueIdentifier
has crossed the line into being too "technically correct" where it doesn't convey the actual use case. However, I'm still glad the feature exists! ๐
Keep learning my friends. ๐ค