javascript - tutorial - react logo
Obtención de la advertencia de apoyo clave en React, aunque la clave está configurada (3)
tl; dr
Cada vez que renderice una lista (use el map
), agregue un atributo de key
único a los elementos de la lista (el elemento superior o "raíz" devuelto por la devolución de llamada del map
):
render() {
return (
<div>
{this.props.data.map( element => {
// Place the key on to the returned "root" element.
// Also, in real life this should be a separate component...
return <div key={element.id}>
<span>Id (Name): </span>
<span>{element.id} </span>
<span>({element.name})</span>
</div>;
})}
</div>
)
}
Explicación
Entendiendo las claves en React
La documentación oficial de Listas y claves muestra cómo debe trabajar con las listas y el documento de conciliaciones vinculado explica los por qué.
Básicamente, cuando React reescribe un componente, ejecuta un algoritmo de diferencias que descubre qué ha cambiado entre la versión nueva y la anterior de la lista. La comparación no siempre es trivial, pero si hay una clave única en cada elemento, se puede identificar claramente lo que ha cambiado. Vea el ejemplo en el documento :
<!-- previous -->
<ul>
<li key="2015">Duke</li>
<li key="2016">Villanova</li>
</ul>
<!-- new -->
<ul>
<li key="2014">Connecticut</li>
<li key="2015">Duke</li>
<li key="2016">Villanova</li>
</ul>
Está claro que se agregó un nuevo elemento con la clave 2014
, ya que tenemos todas las demás claves y esas no se cambiaron. Sin las llaves esto sería oscuro.
Seleccionando una clave adecuada
A partir de ahora es fácil de ver:
- Por qué es importante que la clave sea única, pero solo entre los hermanos en la lista, porque la comparación se realiza solo dentro de los elementos anteriores y nuevos de la lista dada.
- La clave debe seguir siendo la misma para el mismo elemento entre la versión anterior y la nueva, de lo contrario, compararíamos diferentes elementos y no podríamos seguir el cambio. Es por eso que se recomienda usar el id del recurso o (si no tiene uno) algún otro dato que sea único para el elemento, y por qué no debe usar elementos como
Math.random()
.
Colocación de atributo key
en componentes
La convención de que debe colocar el atributo key
en un componente es más una buena práctica, ya que cuando itera una lista y desea representar un elemento, eso indica claramente que debe organizar ese código en un componente separado.
Configuración del atributo key
en el bucle
La declaración que citó de los documentos:
La clave siempre debe suministrarse directamente a los componentes de la matriz, no al contenedor HTML de cada componente en la matriz:
Significa que si procesa componentes en un bucle, entonces debe establecer el atributo key
del componente en el bucle, como lo hizo en su componente EventsTable
:
{this.props.list.map(function (row) {
return (
<Event key={row.WhatId} data={row} />
);
})}
La forma incorrecta es pasarlo al componente donde establecería la key
en sí mismo:
Event = React.createClass({
displayName: ''Event'',
render() {
// Don''t do this!
return (
<tr key={this.props.data.WhatId}>
{_.keys(this.props.data).map((x) => {
Hay otro buen ejemplo para esto en este artículo .
Problema
Estoy recibiendo esta advertencia:
Advertencia: Cada niño en una matriz o iterador debe tener un prop "clave" único. Compruebe el método de renderización de EventsTable. Consulte fb.me/react-warning-keys para obtener más información.
react-runtime-dev.js? 8fefd85d334323f8baa58410bac59b2a7f426ea7: 21998 Advertencia: Cada niño en una matriz o iterador debe tener una prop "clave" única. Compruebe el método de render del evento. Consulte fb.me/react-warning-keys para obtener más información.
Fuente
Esta es la EventsTable
:
EventsTable = React.createClass({
displayName: ''EventsTable'',
render() {
console.dir(this.props.list);
return (
<table className="events-table">
<thead>
<tr>
{_.keys(this.props.list[0]).map(function (key) {
if (key !== ''attributes'') {
return <th>{key}</th>;
}
})}
</tr>
</thead>
<tbody>
{this.props.list.map(function (row) {
return (
<Event key={row.WhatId} data={row} />
);
})}
</tbody>
</table>
)
}
});
Este es el Event
:
Event = React.createClass({
displayName: ''Event'',
render() {
return (
<tr>
{_.keys(this.props.data).map((x) => {
if (x !== ''attributes'')
return <td>{this.props.data[x]}</td>;
})}
</tr>
)
}
});
Pregunta
Claramente tengo la key
apoyo en el componente <Event />
. Y estoy siguiendo la convención de que se supone que debes incluir la key
en el componente, no en el propio HTML (en otras palabras, las etiquetas HTML dentro del componente Event
). Según los documentos oficiales de React:
La clave siempre debe suministrarse directamente a los componentes de la matriz, no al contenedor HTML de cada componente en la matriz:
Estoy muy confundido. ¿Por qué estoy recibiendo advertencias?
¿Has intentado agregar una key
a la etiqueta <th>
?
<tr>
{_.keys(this.props.list[0]).map(function (key) {
if (key !== ''attributes'') {
return <th key={key}>{key}</th>;
}
})}
</tr>
También tuve los problemas, y lo arreglé después de seguir el link .
me gusta:
{_data.map(function(object, i){
return <div className={"row"} key={i}>
{[ object.name ,
<b className="fosfo" key={i}> {object.city} </b> , // remove the key
object.age
]}
</div>;
})}