#javascript #arrays #reactjs
#javascript #массивы #reactjs
Вопрос:
В настоящее время я пытаюсь отфильтровать существующий список элементов по выбранным в раскрывающемся списке выбора. Это означает, что всякий раз, когда я нажимаю на элемент, я хочу удалить его из доступных опций (поэтому я не могу добавить его дважды в список).
Проблема, с которой я сталкиваюсь, заключается в том, что всякий раз, когда я отфильтровываю этот элемент, я не отображаю его на экране (потому что я удалил его из списка). Как я могу удалить элемент из списка доступных опций, но при этом отобразить его на экране? Также, если я решу снова изменить элемент, будет ли предыдущий отображаться в списке снова?
Я подозреваю, что проблема может быть в моей функции фильтрации:
const filterElements = (selectedPerson) => {
let filteredList = people.filter((person) => {
return selectedPerson.id !== person.id;
});
setPeople(filteredList);
};
Вот небольшая программная среда, которую я создал в качестве примера.
Ответ №1:
Я бы посоветовал вам попытаться объяснить проблему немного лучше: возможно, я не понял правильно, но вот мое решение.
Похоже, вы всегда хотите показывать все параметры в раскрывающемся списке, даже если они уже выбраны. Для этого просто сохраните список всех параметров и отобразите каждый из них в пользовательском интерфейсе, даже если они уже были выбраны (отфильтрованы) пользователем. Попробуйте это:
const allPeople = [
{ id: 1, name: "Mark" },
{ id: 2, name: "Peter" },
{ id: 3, name: "John" },
{ id: 4, name: "David" },
{ id: 5, name: " Karen" },
{ id: 6, name: "Johanes" }
]
const [people, setPeople] = useState(allPeople);
const renderOptions = () =>
allPeople.map((person) => { //... your UI));
});
Ответ №2:
Кажется, вы хотите отфильтровать уже выбранные варианты из других входных данных, но не те входные данные, для которых уже выбран данный выбор.
Вы можете сделать это filterElements
, полностью удалив функцию и изменив свою renderOptions
функцию так, чтобы она возвращала только те параметры, которые в данный момент не выбраны (если не выбраны текущим вводом).
Вот как renderedOptions
может выглядеть:
const renderOptions = (selected) => {
const filteredPeople = people.filter(e => e.name === selected || ![selectedOne, selectedTwo, selectedThree].includes(e.name));
return filteredPeople.map((person) => {
return (
<MenuItem value={person.name}>
{person.name}
</MenuItem>
);
});
}
Первое условие в filter
обратном вызове проверяет, выбран ли параметр этим вводом, и включает параметр, если это так, второе условие проверяет, выбран ли параметр любым вводом, и удаляет параметр, если это так. Все остальные параметры будут включены.
Затем вызывайте renderOptions
так:
<Select
name="name"
value={selectedOne}
onChange={(e) => setSelectedOne(e.target.value)}
input={<Input id="name" />}
>
{renderOptions(selectedOne)}
</Select>
<Select
name="name"
value={selectedTwo}
onChange={(e) => setSelectedTwo(e.target.value)}
input={<Input id="name" />}
>
{renderOptions(selectedTwo)}
</Select>
<Select
name="name"
value={selectedThree}
onChange={(e) => setSelectedThree(e.target.value)}
input={<Input id="name" />}
>
{renderOptions(selectedThree)}
</Select>
``
This way the selected options aren't removed entirely, just hidden from those inputs that should not have access to them.
Комментарии:
1. Я видел, что внутри вы выполняете фильтрацию по имени , как в
e.name === selected
. Что, если у меня есть больше полей с одинаковым именем, я бы предпочел, чтобы мы фильтровали по идентификатору.2. @ZombieChowder Я только что сделал это, потому что ваша программа устанавливает значения
selectedX
для personname
, если вы хотите использоватьid
вместо этого, просто заменитеname
сid
вfilter
вызове и изменитеvalue
ofMenuItem
сperson.name
наperson.id
.
Ответ №3:
Было бы проще добавить isVisible
флаг свойства для каждого пользователя и вместо фильтрации просто обновить выбранного пользователя с помощью isVisible = false
const [people, setPeople] = useState([
{ id: 1, name: "Mark", isVisible: true },
{ id: 2, name: "Peter", isVisible: true },
{ id: 3, name: "John", isVisible: true },
{ id: 4, name: "David", isVisible: true },
{ id: 5, name: " Karen", isVisible: true },
{ id: 6, name: "Johanes", isVisible: true }
]);
const filterElements = (selectedPerson) => {
const index = people.findIndex(p => p.id === selectedPerson.id);
selectedPerson[index].isVisible = false;
setPeople(selectedPerson);
};
и здесь просто сделайте:
const renderOptions = () =>
people.filter(p => p.isVisible).map((person) => {
return (
<MenuItem value={person.name} onClick={() => filterElements(person)}>
{person.name}
</MenuItem>
);
});