Reactjs 如何在React中为表单标签生成唯一ID?
我有带有Reactjs 如何在React中为表单标签生成唯一ID?,reactjs,Reactjs,我有带有labels的表单元素,我希望有唯一的ID将labels链接到带有htmlFor属性的元素。大概是这样的: React.createClass({ render() { const id = ???; return ( <label htmlFor={id}>My label</label> <input id={id} type="text"/>
label
s的表单元素,我希望有唯一的ID将label
s链接到带有htmlFor
属性的元素。大概是这样的:
React.createClass({
render() {
const id = ???;
return (
<label htmlFor={id}>My label</label>
<input id={id} type="text"/>
);
}
});
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"/>
);
}
});
<label>
My Label
<input type="text"/>
</label>
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}`} />
);
}
}
import React from 'react'
const Field = props => (
<label>
<span>{props.label}</span>
<input type="text"/>
</label>
)
React.createClass({
render(){
常数id=???;
返回(
我的标签
);
}
});
我以前是根据
这个来生成ID的。_rootNodeID
,但自从React 0.13之后就不可用了。现在最好和/或最简单的方法是什么?这个解决方案对我来说很好
utils/newid.js
:
let lastId = 0;
export default function(prefix='id') {
lastId++;
return `${prefix}${lastId}`;
}
我可以这样使用它:
React.createClass({
render() {
const id = ???;
return (
<label htmlFor={id}>My label</label>
<input id={id} type="text"/>
);
}
});
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"/>
);
}
});
<label>
My Label
<input type="text"/>
</label>
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}`} />
);
}
}
import React from 'react'
const Field = props => (
<label>
<span>{props.label}</span>
<input type="text"/>
</label>
)
从“../utils/newId”导入newId;
React.createClass({
组件willmount(){
this.id=newId();
},
render(){
返回(
我的标签
);
}
});
但它在同构应用程序中不起作用
增加于2015年8月17日。您可以从lodash使用自定义newId函数,而不是自定义newId函数
于2016年1月28日更新。最好在
组件willmount
中生成ID。您可以使用这样的库来确保获得唯一的ID
安装时使用:
npm安装节点uuid——保存
然后在react组件中添加以下内容:
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>
);
}
}
从“节点UUID”导入{默认为UUID};
从“React”导入{default as React};
导出默认类MyComponent扩展React.Component{
组件willmount(){
this.id=UUID.v4();
},
render(){
返回(
我的标签
);
}
}
id应该放在componentWillMount(2018年更新)的内部构造函数
,而不是渲染
。将其放入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>
);
}
构造函数(道具){
超级(道具);
this.id=ux.uniqueId(“前缀-”);
}
render(){
const id=this.id;
返回(
标签
);
}
2019年更新:
import React, { useState } from 'react';
import _uniqueId from 'lodash/uniqueId';
const MyComponent = (props) => {
// id will be set once when the component initially renders, but never again
// (unless you assigned and called the second argument of the tuple)
const [id] = useState(_uniqueId('prefix-'));
return (
<div>
<input id={id} type="checkbox" />
<label htmlFor={id}>label</label>
</div>
);
}
import React,{useState}来自“React”;
从“lodash/uniqueId”导入“uniqueId”;
常量MyComponent=(道具)=>{
//id将在组件最初渲染时设置一次,但不会再次设置
//(除非指定并调用元组的第二个参数)
const[id]=useState(_uniqueId('prefix-');
返回(
标签
);
}
希望这对任何来寻找通用/同构解决方案的人都有帮助,因为校验和问题是我首先想到的
如上所述,我已经创建了一个简单的实用程序来按顺序创建一个新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 }
然后在根组件的构造函数或组件willmount中,调用reset。这实际上会在每个服务器渲染中重置服务器的JS作用域。在客户端中,它没有(也不应该)任何效果。如果不需要,请不要使用ID,而是将输入包装在如下标签中:
React.createClass({
render() {
const id = ???;
return (
<label htmlFor={id}>My label</label>
<input id={id} type="text"/>
);
}
});
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"/>
);
}
});
<label>
My Label
<input type="text"/>
</label>
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}`} />
);
}
}
import React from 'react'
const Field = props => (
<label>
<span>{props.label}</span>
<input type="text"/>
</label>
)
我的标签
这样,您就不必担心唯一ID。从2019-04-04年开始,这似乎可以通过React钩子实现: 或者在这里查看我发布的库:。还有成百上千的其他独一无二的ID,但是lodash的带有前缀的uniqueId应该足以完成任务
更新2019-07-10 感谢@Huong Hk为我指点,其总和是您可以将函数传递到
useState
,该函数将仅在初始装载时运行
// before
const [ id ] = useState(uniqueId('myprefix-'))
// after
const [ id ] = useState(() => uniqueId('myprefix-'))
我找到了这样一个简单的解决方案:
React.createClass({
render() {
const id = ???;
return (
<label htmlFor={id}>My label</label>
<input id={id} type="text"/>
);
}
});
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"/>
);
}
});
<label>
My Label
<input type="text"/>
</label>
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}`} />
);
}
}
import React from 'react'
const Field = props => (
<label>
<span>{props.label}</span>
<input type="text"/>
</label>
)
类切换开关扩展组件{
静态id;
建造师(道具){
超级(道具);
if(typeof-ToggleSwitch.id===“未定义”){
ToggleSwitch.id=0;
}否则{
ToggleSwitch.id+=1;
}
this.id=ToggleSwitch.id;
}
render(){
返回(
);
}
}
对于标签
和输入
的常用用法,将输入封装到如下标签中更容易:
React.createClass({
render() {
const id = ???;
return (
<label htmlFor={id}>My label</label>
<input id={id} type="text"/>
);
}
});
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"/>
);
}
});
<label>
My Label
<input type="text"/>
</label>
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}`} />
);
}
}
import React from 'react'
const Field = props => (
<label>
<span>{props.label}</span>
<input type="text"/>
</label>
)
从“React”导入React
常量字段=道具=>(
{props.label}
)
它还可以在复选框/单选按钮中对根元素应用填充,并且仍然可以获得点击输入的反馈。我创建了一个uniqueId生成器模块(Typescript): 并使用top模块生成唯一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>
);
};
从'React'导入React,{FC,ReactElement}
从“../../modules/uniqueId”导入uniqueId;
常量组件:FC=():ReactElement=>{
const[inputId]=useState(uniqueId('input-');
返回(
文本
);
};
如果您一次又一次地生成这个元素,我在for语句中假设为什么不在它上面使用迭代器?我想如果索引号不够好,还可以调用一个生成唯一guid的函数。在不同的组件中有许多不同的表单元素,它们都应该有唯一的ID。生成ID的函数是我所想的,如果没有人建议更好的解决方案,我将做什么。您可以在某个地方存储一个“全局”递增计数器并使用它<代码>id=‘唯一’+(++GLOBAL_id)代码>其中var GLOBAL\u ID=0
?我知道我参加这次聚会已经非常非常晚了,但另一种选择是将输入内容包装在标签中,而不是使用ID,例如:My label
,因为它将再次在浏览器中从第一个开始生成ID。但实际上,您可以在服务器和浏览器中使用不同的前缀。不要在渲染中这样做!在componentWillMount
中创建id您已经创建了一个有状态的容器,但是忽略了使用setState,并且违反了规范f