Solución:
La identificación debe colocarse dentro de componenteWillMount (actualización para 2018) constructor
, no render
. Poniéndolo en render
volverá a generar nuevos ID innecesariamente.
Si usa guión bajo o lodash, hay un uniqueId
función, por lo que su código resultante debería ser algo como:
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>
);
}
Actualización de Hooks 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>
);
}
Esta solución funciona bien para mí.
utils/newid.js
:
let lastId = 0;
export default function(prefix='id') {
lastId++;
return `${prefix}${lastId}`;
}
Y puedo usarlo así:
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"/>
);
}
});
Pero no funcionará en aplicaciones isomórficas.
Añadido 17.08.2015. En lugar de la función newId personalizada, puede usar uniqueId de lodash.
Actualizado 28.01.2016. Es mejor generar ID en componentWillMount
.
Siguiendo a partir del 2019-04-04, esto parece poder lograrse con los 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
Según tengo entendido, ignora el segundo elemento de la matriz en la desestructuración de la matriz que le permitiría actualizar id
, y ahora tiene un valor que no se actualizará nuevamente durante la vida útil del componente.
El valor de id
estarán myprefix-<n>
dónde <n>
es un valor entero incremental devuelto por uniqueId
. Si eso no es lo suficientemente único para usted, considere hacer su propio Me gusta
function gen4() {
return Math.random().toString(16).slice(-4)
}
function simpleUniqueId(prefix) {
return (prefix || '').concat([
gen4(),
gen4(),
gen4(),
gen4(),
gen4(),
gen4(),
gen4(),
gen4()
].join(''))
}
o echa un vistazo a la biblioteca que publiqué con esto aquí: https://github.com/rpearce/simple-uniqueid. También hay cientos o miles de otras cosas de identificación únicas por ahí, pero lodash’s uniqueId
con un prefijo debería ser suficiente para hacer el trabajo.
Actualización 2019-07-10
Gracias a @Huong Hk por señalarme el estado inicial perezoso de los ganchos, cuya suma es que puedes pasar una función a useState
que solo se ejecutará en el montaje inicial.
// before
const [ id ] = useState(uniqueId('myprefix-'))
// after
const [ id ] = useState(() => uniqueId('myprefix-'))