Элемент localstorage не очищается при размонтировании компонента React

У меня есть несколько компонентов React, и они используют локальное хранилище для хранения некоторой информации. Они привязаны к переменным состояния с помощью пользовательского хука:

export const useLocalStorage = (key, defaultValue) => {
    const [value, setValue] = useState(() => {
        return getStorageValue(key, defaultValue);
    });

    useEffect(() => {
        localStorage.setItem(key, JSON.stringify(value));
    }, [key, value]);

    return [value, setValue];
}

Компонент использует это как:

const [thing, setThing] = useLocalStorage('thing', '');

Теперь я хочу очистить это, когда компонент размонтируется.

Я попытался очистить это с помощью useEffect:

useEffect(() => {
    return () => {
        setThing(prevThing => '');
    }
},[]);

Однако, похоже, это не работает. Я даже могу консольно войти в очистку функции и увидеть это, но изменение состояния и последующая очистка localstorage не происходит. Я не уверен, как это правильно очистить.

Изменить (добавив getStorageValue):

const getStorageValue = (key, defaultValue) => {
    let value;
    try {
        const saved = localStorage.getItem(key);
        value = JSON.parse(saved);

    } catch(err) {
        value = false;
    }

    return value || defaultValue;
}

Под правильной очисткой вы имеете в виду удаление элемента из localStorage или установку его в пустую строку? Вы можете использовать localStorage.removeItem(itemName), чтобы удалить элемент из локального хранилища.

ionosphere 22.05.2023 00:05

Либо должно быть хорошо. Я избегал прямого редактирования localstorage, чтобы предотвратить его рассинхронизацию с тем, что находится в состоянии, но я полагаю, что если компонент размонтируется, это не имеет значения. Быстрый тест показывает, что прямое удаление происходит. Я все еще хотел бы знать, почему это не работает как есть.

zombiedev 22.05.2023 00:20

Можете ли вы включить код для getStorageValue?

ionosphere 22.05.2023 00:24

Добавлено по запросу.

zombiedev 22.05.2023 00:31

Вы не используете значение prevState при очистке состояния, так почему бы вам просто не вызвать setThing(“”) в функции очистки? Я не понимаю, почему это может быть проблемой, но стоит проверить, поскольку вызов setState здесь немного неортодоксален.

ionosphere 22.05.2023 00:37

Это кажется маловероятным. Обычно рекомендуется передавать состояние как функцию, чтобы убедиться, что вы имеете дело с последними значениями. Хотя я не использую его, я делаю это по привычке, и никогда не было проблем. Это также отлично работает с другими вещами локального хранилища, которые изменяются. Кажется, это связано с процессом размонтирования.

zombiedev 22.05.2023 01:03
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
2
6
71
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Локальное состояние компонента React ничего не знает о localStorage. Если ваш хук устанавливает что-то в локальное хранилище, то задача хука - очистить его при размонтировании, если это необходимо.

Это не произойдет автоматически.

Ну, я не удалял элемент localstorage. Я просто устанавливал новое значение ''. Этот вызов изменения состояния в unmount является перехватчиком состояния в useLocalstorage. Эффект использования в uselocalstorage обновляет локальное хранилище при изменении состояния.

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

Если я правильно понимаю, вы пытались установить значение "", ожидая, что обратный вызов useEffect будет запущен в ответ, и установить элемент localStorage на "". Однако установка этого значения невозможна, поскольку компонент уже размонтирован. Вы должны увидеть предупреждение в консоли, когда это произойдет.

К счастью, вы все еще можете получить доступ к localStorage из обратного вызова очистки, поскольку это не зависит от компонента.

useEffect(() => {
    return () => {
        localStorage.setItem(key, '');
    }
}, [key]);

Этот вызов хука установит элемент в "", когда key изменится или компонент будет размонтирован.


Кстати, Storage.setItem(key, '') не сбрасывает значение ключа, а устанавливает пустую строку в качестве его значения. Чтобы сбросить ключ, используйте Storage.removeItem(key).

Ага. Я был своего рода общим о неустановленном и очистившем значении. Noop был единственной вещью, о которой я мог думать, что это может быть причиной того, что этого не произошло. Я знаю, почему они это делают, но в данном случае изменение состояния noop имеет последствия, которых нет из-за эффекта использования. Ну ладно, для этого мне просто придется работать напрямую с локальным хранилищем. Спасибо за подтверждение поведения.

zombiedev 24.05.2023 03:05

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