我正在尝试从 GraphQL 查询结果生成下拉选项,该结果是一个包含数组的对象。由于 TypeScript 不支持对象迭代,我尝试使用纯 JavaScript 来迭代数据。当我简单地按照它的工作方式编写它时:
const unique = Array.from(
new Set(data.PlayerDetails.map((item: any) => item.country))
);
console.log(unique);
但是当我把它放在 JSX 中时它不起作用。可能是什么原因?
...
return (
<p>
<Bold>Players: </Bold>
<select className="form-control">
{Array.from(
new Set(
data.PlayerDetails.map((player: any) => {
return (
<option key={player.id} value={player.country}>
{player.country}
</option>
);
})
)
)}
</select>
</p>
);
预计: 在 <option>...</option>
中删除了重复项.
实际结果: <option>...</option>
仍然显示所有重复的数据,但以前的代码“唯一”显示没有重复的数据。
最佳答案
它与 JSX 无关,您在这些代码片段中做了两件截然不同的事情。
首先,您通过将玩家条目映射到他们的国家值并将其传递给 Set
来消除重复项。仅获取唯一的国家/地区值。
在您的代码中创建 <option>
元素,您正在创建对象。这些将是唯一的,因为每个对象都是唯一的,即使它具有相同的内容。
我的第一个想法是预先过滤播放器数据数组以删除重复项,然后将结果映射到 <option>
元素。例如:
const countries = new Set();
const uniquePlayers = data.PlayerDetails.filter(({country}) => {
if (countries.has(country)) {
return false;
}
countries.add(country);
return true;
});
return (
<select className="form-control">
{uniquePlayers.map((player/*: any*/) => {
return (
<option key={player.id} value={player.country}>
{player.country}
</option>
);
})}
</select>
);
实例:
const data = {
PlayerDetails: [
{
id: 1,
country: "China"
},
{
id: 2,
country: "USA"
},
{
id: 3,
country: "Finland"
},
{
id: 1, // Duplicate
country: "China"
}
]
};
const Example = () => {
const countries = new Set();
const uniquePlayers = data.PlayerDetails.filter(({country}) => {
if (countries.has(country)) {
return false;
}
countries.add(country);
return true;
});
return (
<select className="form-control">
{uniquePlayers.map((player/*: any*/) => {
return (
<option key={player.id} value={player.country}>
{player.country}
</option>
);
})}
</select>
);
};
ReactDOM.render(<Example />, document.getElementById("root"));
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
...但实际上,您可以进行唯一检查并创建 <option>
单程中的元素。你可能没有那么多<option>
从性能 Angular 来看它很重要的元素,但它使代码更简单:
const options = new Map();
for (const player of data.PlayerDetails) {
const {country} = player;
if (!options.has(country)) {
options.set(
country,
<option key={player.id} value={player.country}>
{player.country}
</option>
);
}
}
return (
<select className="form-control">
{options.values()}
</select>
);
实例:
const data = {
PlayerDetails: [
{
id: 1,
country: "China"
},
{
id: 2,
country: "USA"
},
{
id: 3,
country: "Finland"
},
{
id: 1, // Duplicate
country: "China"
}
]
};
const Example = () => {
const options = new Map();
for (const player of data.PlayerDetails) {
const {country} = player;
if (!options.has(country)) {
options.set(
country,
<option key={player.id} value={player.country}>
{player.country}
</option>
);
}
}
return (
<select className="form-control">
{options.values()}
</select>
);
};
ReactDOM.render(<Example />, document.getElementById("root"));
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
关于javascript - 为什么 Array.from(new Set) 在 React jsx 中不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54980617/