我试图从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>
仍然显示所有具有重复项的数据,但前一代码“unique”显示没有重复的数据。
它与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>
元素,但它使代码更简单:
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>