A npm package that allows you to use unique html IDs for components.
This module allows you to set unique id
tags on React HTML elements,
mainly in order to connect labels to them but also for other HTML function
that require unique ids (#references
).
To use the module, you first need to inject the extension into
your component. You do this via the enableUniqueIds
function
(which is the only function exposed by this module). Then you
can use this.nextUniqueId()
to get a new identifier,
this.lastUniqueId()
to refer to that identifier again in the HTML,
and this.getUniqueId('name')
to get an identifier by name.
class MyComponent {
constructor() {
super()
enableUniqueIds(this)
}
render () {
// Use nextUniqueId to create a new ID, and lastUniqueId to refer to the same ID again
return (
<div className="form-group">
<label htmlFor={this.nextUniqueId()}>Name</label>
<input id={this.lastUniqueId()}
type="text"
className="control" />
</div>
)
}
}
The problem with using a local counter in the render function is that the IDs will not be unique between different instance.
class BadComponent {
render () {
var idCounter = 0;
// Do not do this!!
return (
<div className="form-group">
<label htmlFor={'id-' + idCounter}>Name</label>
<input id={'id-' + idCounter}
type="text"
className="control" />
</div>
)
}
}
If you put two instances of BadComponent
in your React application,
they will both share the same IDs! This package ensures you will get
unique IDs per instance of every component.
This should be called from the constructor of the component that needs unique IDs,
passing this
as the parameter. After calling this you can use nextUniqueId
, lastUniqueId
and getUniqueId
by invoking them on this
.
This call either adds a componentWillUpdate
handler to the current component,
or wraps the existing one. The package uses componentWillUpdate
to reset the
ID counter every time the component re-renders.
class MyComponent {
constructor() {
super()
// Enable Unique ID support for this class
enableUniqueIds(this)
}
render() {
// ...
}
}
This will returns a new unique id for the component. Repeatedly calling this function will result in new IDs.
IDs are consistent between renders, as long as the function is always called in the same order. This means there are no DOM updates necessary if you do not remove calls to the function between renders.
render() {
var manyFields = ['firstName', 'lastName', 'address', 'postalCode', 'city']
// Every label-input pair will have a unique ID
return (
<form>
{manyFields.map((field, index) => {
return (
<div className="form-group" key={index}>
<label htmlFor={this.nextUniqueId()}>Name</label>
<input id={this.lastUniqueId()}
type="text"
className="control" />
</div>
)
})
</form>
)
}
Returns the same ID that was returned by the last call to nextUniqueId
,
this is almost always necessary as you need to refer to the ID twice, once
for the label and once for the input.
This always returns the same unique identifier, given the same name.
This is useful if the order of components makes it impossible or confusing
to use lastUniqueId
to refer to a component.
render() {
return (
<div className="form-group" key={index}>
<label htmlFor={this.getUniqueId('input')}>Name</label>
<div className="help-block"
id={this.getUniqueId('help')}>
This should be your full name.
</div>
<input id={this.getUniqueId('input')}
type="text"
aria-describedby={this.getUniqueId('help')}
className="control" />
</div>
)
}
You can of course also store the result of nextUniqueId
into a variable
to acheive the same result.
This simple extension is brough to you by Hampus Nilsson.