javascript - 为什么 Array.from(new Set) 在 React jsx 中不起作用

标签 javascript reactjs typescript

我正在尝试从 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/

相关文章:

javascript - 带循环的 NodeJS 异步控制流

javascript - 多个条件与多个语句

javascript - react : strange behaviour on hover

angular - Angular 2.0.1 中的@Inject 自定义提供程序

JavaScript:检测移动嵌入式浏览器(强制门户)

javascript - 我如何在firebase数据库中检索多级数据--Webapp

javascript - rails/ react : Refs Must Have Owner

javascript - d3.js 中单元格尺寸太小时删除文本

javascript - 带有参数的 Typeorm 监听器

typescript - 将 Uglify 与 TypeScript 和 Webpack 2 结合使用