Реагировать на обновление useState проблематично

Привет, сообщество Stackoverflow,

У меня сложная проблема с useState. Я хочу удалить элемент из массива, а после этого хочу выполнить несколько проверок и выполнить вызов xhr. Позволь мне привести пример:

const [items, setItems] = useState([{ id: 'xxx', email: '[email protected]' }, { id: 'yyy', email: '[email protected]' }]);

const handleRemoveItem = async (index) => {
    const itemEmail = items[index].email;
    const itemsCopy = [...items];
    itemsCopy.splice(index, 1); <-- Remove one item, one should be left
    setItems(itemsCopy);

    const isUnique = await checkUnique(email);
    if(!isUnique) {
        // do something
    }
}

const checkUnique = async (email) => {
    const hasDuplicates = items.filter(item => item.email === email).length > 1; <-- items has already 2 items, but before one was removed
    if(hasDuplicates) {
        return false;
    }

    // Some XHR calls to check the email already exists

}

Проблема в том, что элементы в checkUnique по-прежнему содержат два элемента. Я не могу использовать useEffect, потому что мне нужен удаленный элемент в вызове xhr. И я не хочу вспоминать удаленный элемент, потому что он сложен для понимания и избыточен. Есть ли у кого-нибудь идеи, как решить эту проблему? Я думал о передаче itemsCopy в checkUnique в качестве параметра, но можно ли это сделать?


person Jan Höck    schedule 08.04.2020    source источник
comment
Да, это было бы подходящим вариантом, передав itemsCopy в checkUnique, а затем используя это, чтобы отфильтровать массив и проверить, есть ли в нем дубликаты.   -  person goto1    schedule 08.04.2020
comment
Хорошо, но иногда я могу вызвать метод checkUnique без параметра itemsCopy. Должен ли параметр items получить значение по умолчанию?: const checkUnique = async (email, arr = items)   -  person Jan Höck    schedule 08.04.2020
comment
Это может сработать, но вы не должны полагаться на items постоянную актуальность, и вы можете получить странные результаты. Что я бы сделал, так это попытаться сохранить эту функцию как можно более чистой и всегда передавать все необходимые аргументы, чтобы было легче отлаживать, вместо того, чтобы полагаться на переменные за пределами области checkUnique.   -  person goto1    schedule 08.04.2020


Ответы (1)


Просто используйте это так; Должно помочь;

const handleRemoveItem = async (index) => {
const itemEmail = items[index].email;

setItems((prevState) => {
  return prevState.splice(index, 1);
});

const isUnique = await checkUnique(itemEmail);
if (!isUnique) {
  // do something
}
};
person dima bgood    schedule 08.04.2020
comment
На самом деле это ни в чем не помогает. - person goto1; 08.04.2020
comment
Чем ваше решение отличается от моего текущего примера? - person Jan Höck; 08.04.2020