Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs 如何在React中为表单标签生成唯一ID?_Reactjs - Fatal编程技术网

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