У меня есть несколько компонентов 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, чтобы предотвратить его рассинхронизацию с тем, что находится в состоянии, но я полагаю, что если компонент размонтируется, это не имеет значения. Быстрый тест показывает, что прямое удаление происходит. Я все еще хотел бы знать, почему это не работает как есть.
Можете ли вы включить код для getStorageValue?
Добавлено по запросу.
Вы не используете значение prevState при очистке состояния, так почему бы вам просто не вызвать setThing(“”) в функции очистки? Я не понимаю, почему это может быть проблемой, но стоит проверить, поскольку вызов setState здесь немного неортодоксален.
Это кажется маловероятным. Обычно рекомендуется передавать состояние как функцию, чтобы убедиться, что вы имеете дело с последними значениями. Хотя я не использую его, я делаю это по привычке, и никогда не было проблем. Это также отлично работает с другими вещами локального хранилища, которые изменяются. Кажется, это связано с процессом размонтирования.





Локальное состояние компонента React ничего не знает о localStorage. Если ваш хук устанавливает что-то в локальное хранилище, то задача хука - очистить его при размонтировании, если это необходимо.
Это не произойдет автоматически.
Ну, я не удалял элемент localstorage. Я просто устанавливал новое значение ''. Этот вызов изменения состояния в unmount является перехватчиком состояния в useLocalstorage. Эффект использования в uselocalstorage обновляет локальное хранилище при изменении состояния.
Если я правильно понимаю, вы пытались установить значение "", ожидая, что обратный вызов useEffect будет запущен в ответ, и установить элемент localStorage на "". Однако установка этого значения невозможна, поскольку компонент уже размонтирован. Вы должны увидеть предупреждение в консоли, когда это произойдет.
К счастью, вы все еще можете получить доступ к localStorage из обратного вызова очистки, поскольку это не зависит от компонента.
useEffect(() => {
return () => {
localStorage.setItem(key, '');
}
}, [key]);
Этот вызов хука установит элемент в "", когда key изменится или компонент будет размонтирован.
Кстати, Storage.setItem(key, '') не сбрасывает значение ключа, а устанавливает пустую строку в качестве его значения. Чтобы сбросить ключ, используйте Storage.removeItem(key).
Ага. Я был своего рода общим о неустановленном и очистившем значении. Noop был единственной вещью, о которой я мог думать, что это может быть причиной того, что этого не произошло. Я знаю, почему они это делают, но в данном случае изменение состояния noop имеет последствия, которых нет из-за эффекта использования. Ну ладно, для этого мне просто придется работать напрямую с локальным хранилищем. Спасибо за подтверждение поведения.
Под правильной очисткой вы имеете в виду удаление элемента из localStorage или установку его в пустую строку? Вы можете использовать
localStorage.removeItem(itemName), чтобы удалить элемент из локального хранилища.