Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Label IDs for React

Tags:

html

reactjs

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:

  • Pass unique idkey all the way - but that means not just this component but every parent, grandparent, etc., using it now needs a unique idkey.
  • Use Math.random() to generate them - that makes render() non-deterministic, which feels wrong.
  • Generate a random key with Math.random() when component gets created/mounted, so render() itself would be deterministic.
  • Just turn that whole container into <label> and rewrite the CSS a bit to make it work.
  • Give that <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?

like image 369
taw Avatar asked Nov 15 '25 20:11

taw


1 Answers

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>
like image 143
dance2die Avatar answered Nov 17 '25 10:11

dance2die



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!