如何在React中为表单标签生成唯一ID?

时间:2015-04-02 19:22:37

标签: reactjs

我的表单元素包含label,我希望使用唯一ID将label链接到具有htmlFor属性的元素。像这样:

React.createClass({
    render() {
        const id = ???;
        return (
            <label htmlFor={id}>My label</label>
            <input id={id} type="text"/>
        );
    }
});

我曾经根据this._rootNodeID生成ID,但自React 0.13起它无法使用。现在最好和/或最简单的方法是什么?

9 个答案:

答案 0 :(得分:78)

此解决方案适用于我。

utils/newid.js

let lastId = 0;

export default function(prefix='id') {
    lastId++;
    return `${prefix}${lastId}`;
}

我可以这样使用它:

import newId from '../utils/newid';

React.createClass({
    componentWillMount() {
        this.id = newId();
    },
    render() {
        return (
            <label htmlFor={this.id}>My label</label>
            <input id={this.id} type="text"/>
        );
    }
});

但它不适用于同构应用程序。

已添加17.08.2015 。您可以使用lodash中的uniqueId代替自定义newId函数。

已于2016年1月28日更新。最好在componentWillMount生成ID。

答案 1 :(得分:57)

id应该放在 componentWillMount (2018年更新)constructor内,而不是render。将其放入render将不必要地重新生成新的ID。

如果您使用下划线或lodash,则会有一个uniqueId函数,因此您生成的代码应该类似于:

constructor(props) {
    super(props);
    this.id = _.uniqueId("prefix-");
}

render() { 
  const id = this.id;
  return (
    <div>
        <input id={id} type="checkbox" />
        <label htmlFor={id}>label</label>
    </div>
  );
}

答案 2 :(得分:2)

您可以使用node-uuid等库来确保获得唯一ID。

使用安装:

npm install node-uuid --save

然后在您的反应组件中添加以下内容:

import {default as UUID} from "node-uuid";
import {default as React} from "react";

export default class MyComponent extends React.Component {   
  componentWillMount() {
    this.id = UUID.v4();
  }, 
  render() {
    return (
      <div>
        <label htmlFor={this.id}>My label</label>
        <input id={this.id} type="text"/>
      </div>
    );
  }   
}

答案 3 :(得分:2)

自2019年4月4日起,这似乎可以通过React Hooks的useState完成:

import React, { useState } from 'react'
import uniqueId from 'lodash/utility/uniqueId'

const Field = props => {
  const [ id ] = useState(uniqueId('myprefix-'))

  return (
    <div>
      <label htmlFor={id}>{props.label}</label>
      <input id={id} type="text"/>
    </div>
  )      
}

export default Field

据我了解,您忽略了数组解构中的第二个数组项,该数组项允许您更新id,现在您拥有的值在整个生命周期中都不会再次更新组件。

id的值将为myprefix-<n>,其中<n>是从uniqueId返回的增量整数值。如果那还不够独特,请考虑按照自己的喜好

function gen4() {
  return Math.random().toString(16).slice(-4)
}

function simpleUniqueId(prefix) {
  return (prefix || '').concat([
    gen4(),
    gen4(),
    gen4(),
    gen4(),
    gen4(),
    gen4(),
    gen4(),
    gen4()
  ].join(''))
}

,或在https://github.com/rpearce/simple-uniqueid处查看我以此发布的库。还有成百上千的其他唯一ID东西,但是lodash的带有前缀的uniqueId应该足以完成工作。

答案 4 :(得分:1)

希望这对任何想要寻找通用/同构解决方案的人都有帮助,因为校验和问题首先引起了我的兴趣。

如上所述,我创建了一个简单的实用程序来顺序创建一个新的id。由于ID在服务器上不断递增,并且从客户端的0开始,我决定在每次SSR开始时重置增量。

// utility to generate ids
let current = 0

export default function generateId (prefix) {
  return `${prefix || 'id'}-${current++}`
}

export function resetIdCounter () { current = 0 }

然后在根组件的构造函数或componentWillMount中,调用reset。这实质上重置了每个服务器渲染中服务器的JS范围。在客户端,它没有(并且不应该)有任何影响。

答案 5 :(得分:1)

我创建一个uniqueId生成器模块(Typescript):

const uniqueId = ((): ((prefix: string) => string) => {
  let counter = 0;
  return (prefix: string): string => `${prefix}${++counter}`;
})();

export default uniqueId;

并使用顶部模块生成唯一的ID:

import React, { FC, ReactElement } from 'react'
import uniqueId from '../../modules/uniqueId';

const Component: FC = (): ReactElement => {
  const [inputId] = useState(uniqueId('input-'));
  return (
    <label htmlFor={inputId}>
      <span>text</span>
      <input id={inputId} type="text" />
    </label>
  );
};     

答案 6 :(得分:0)

对于labelinput的通常用法,将输入包装到这样的标签中会更容易:

import React from 'react'

const Field = props => (
  <label>
    <span>{props.label}</span>
    <input type="text"/>
  </label>
)      

这还使得可以在复选框/单选按钮中将填充应用于根元素,并且仍然获得单击输入的反馈。

答案 7 :(得分:-1)

我找到了一个像这样的简单解决方案:

class ToggleSwitch extends Component {
  static id;

  constructor(props) {
    super(props);

    if (typeof ToggleSwitch.id === 'undefined') {
      ToggleSwitch.id = 0;
    } else {
      ToggleSwitch.id += 1;
    }
    this.id = ToggleSwitch.id;
  }

  render() {
    return (
        <input id={`prefix-${this.id}`} />
    );
  }
}

答案 8 :(得分:-2)

Don't use IDs at all if you don't need to, instead wrap the input in a label like this:

<label>
   My Label
   <input type="text"/>
</label>

Then you won't need to worry about unique IDs.