如何在ReactJS中将对象引用用作{key}?
我试过这个:
let ruleList = _.map(this.state.rules, function(rule) {
return <RuleList rule={rule} key={rule} />
});
但最终会在控制台中打印出来:
警告:flattenChildren(...):遇到两个孩子一样 键,
.0:$[object Object]
。子键必须是唯一的;当两个 孩子们共用一把钥匙,只会使用第一个孩子。
有没有办法解决这个问题,而不是为每个项目生成ID?
答案 0 :(得分:1)
我遇到过类似的情况,即对象没有唯一的ID。
我最终根据对象引用生成了商品的ID:
let curId = 1;
const ids = new WeakMap();
function getObjectId(object) {
if (ids.has(object)) {
return ids.get(object);
} else {
const id = String(curId++);
ids.set(object, id);
return id;
}
}
// Usage
<RuleList rule={rule} key={getObjectId(rule)} />
我知道您提到您不想生成id,但是我想分享一下,因为它是通用的,并且不依赖于对象中的任何属性。
答案 1 :(得分:1)
我创建了一个库来解决这个问题。它基于@amann 建议的想法(使用weakMap)。它提供了一个钩子,使weakMap随组件一起创建和销毁。
看看https://www.npmjs.com/package/react-key-from-object
import { useKeyGen } from 'react-key-from-object'
const DogList = () => {
const keyGen = useKeyGen();
return (
<ul>
{dogs.map((dog) => (
<li key={keyGen.getKey(dog)}>
{dog.name}
-
{dog.age}
</li>
))
</ul>
);
}
答案 2 :(得分:0)
对象不能用作键。 React js要求键是字符串或数字,并且应该是唯一的。
IMO有两种方法可以解决这个问题(对建议开放)
遍历数组并创建唯一索引
var rules = data.rules;
for(var i=0;i<rules.length;i++){
data.rules[i].key = i;
}
在_.map
let ruleList = _.map(this.state.rules, function(rule) {
return <RuleList rule={rule} key={rule.key} />
});
维护未删除的规则对象索引数组。
var N = rules.length;
var arrayOfRules = Array.apply(null, {length: N}).map(Number.call, Number);
删除项目时,请使用.splice将其删除。
组件应如下所示
let ruleList = _.map(this.state.rules, function(rule, index) {
return <RuleList rule={rule} key={arrayOfRules[index]} />
});
由于规则对象没有唯一且属性必须唯一的属性,因此请添加map方法中的index参数。
let ruleList = _.map(this.state.rules, function(rule, index) { // <--- notice index parameter
return <RuleList rule={rule} key={index} />
});
答案 3 :(得分:-1)
为什么坚持使用规则对象作为密钥?
最简单的解决方案是使用从下划线地图函数返回的索引。像这样:
let ruleList = _.map(this.state.rules, function(rule, index) {
return <RuleList rule={rule} key={index} />
});
这是与地图功能相关的similar topic。