Почему Array.from(новый набор) не будет работать в React jsx

Я пытаюсь сгенерировать параметры раскрывающегося списка из результата запроса GraphQL, который представляет собой объект, содержащий массив. Поскольку TypeScript не поддерживает итерацию объектов, я пытался использовать чистый JavaScript для итерации данных. Когда я просто пишу это следующим образом, это работает:

const unique = Array.from(
 new Set(data.PlayerDetails.map((item: any) => item.country))
);
console.info(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» показывает данные без дубликатов.

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
4
10
1 110
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Это не имеет ничего общего с 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>

Другие вопросы по теме