Reputation: 18871
So HTML has this awkward problem that to make label
work with input
, they need to be linked by a matching id
/for
(renamed by React to htmlFor
) pair.
Here's some simplified code with change handles, etc., skipped:
class CheckboxComponent extends Component {
render() {
let {selected,name,idkey} = this.props;
let id = `checkbox-${idkey}`;
return <div>
<input type="checkbox" id={id} checked={selected}/>
<label htmlFor={id}>{name}</label>
</div>;
}
}
Is there any reasonable way to generate those IDs? There are some options but all of them seem really awkward:
idkey
all the way - but that means not just this component but every parent, grandparent, etc., using it now needs a unique idkey
.Math.random()
to generate them - that makes render()
non-deterministic, which feels wrong.Math.random()
when component gets created/mounted, so render()
itself would be deterministic.<label>
and rewrite the CSS a bit to make it work.<label>
no for
at all, instead some kind of onClick
handler to find sibling <input>
with DOM API... That's quite straightforward in jQuery-based code, but quite a bit of a mess in React.Is one of these solutions actually standard practice? Am I missing something else better?
Upvotes: 4
Views: 6069
Reputation: 10814
These days, you can use the useId
hook offered by React itself.
import { useId } from 'react';
const CheckboxComponent = ({ selected, name }) => {
const id = useId();
return (
<div>
<input type="checkbox" id={id} checked={selected} />
<label htmlFor={id}>{name}</label>
</div>
);
};
Upvotes: 0
Reputation: 36955
According to your comment, it seems like id
can be any random number.
You can use a library called short-id just to generate random IDs.
It has an option to configure how ID is generated but in your case it doesn't seem to matter
import shortid from 'short-id'
class CheckboxComponent extends Component {
render() {
let {selected,name,idkey} = this.props;
let id = shortid.generate();
return <div>
<input type="checkbox" id={id} checked={selected}/>
<label htmlFor={id}>{name}</label>
</div>;
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
Upvotes: 2