Пишем свой хук для отслеживания изменений в LocalStorage

от автора

В рамках своей работы, я не раз сталкивался с проблемой, что нужно отслеживать изменение в LocalStorage в совершенно независимых компонентах.

Были попытки отслеживания изменений через «window.addEventListener», но и тут меня ждала неудача, так как в этом случае отслеживание будет происходить только в другой вкладке браузера и тем самым я дошел до создания своего хука, назвал его — useLocalStorageEffect. Далее уже будем говорить о нем.

Какие проблемы решает хук useLocalStorageEffect:

  • Отслеживание изменений происходит в любом месте вашего приложения

  • Вам не обязательно волноваться о перезагрузке вашей страницы, для того что бы информация обновилась

  • Код выглядит лаконично и понятно

Обязательным элементом для использования этого хука является усовершенствованный метод для установки значения по ключу в LocalStoarge.

Метод setLocalStorageItem

import _ from 'lodash'  export const setLocalStorageItem = (key, value) => { if (typeof window !== 'undefined') { if (key) { const data = window.localStorage.getItem(key)  if (_.isNil(data)) { if (_.isUndefined(value)) { window.localStorage.setItem(key, null)  return null }  window.localStorage.setItem(key, JSON.stringify(value)) }  window.localStorage.setItem(key, JSON.stringify(value))  const event = new StorageEvent('storage', { isTrusted: true, bubbles: true, cancelable: false, key: key, oldValue: data, newValue: JSON.stringify(value) })  window.dispatchEvent(event) }  return null }  return null }

Метод setLocalStorageItem решает проблему отслеживания событий в текущей вкладке браузера.

Хук useLocalStorageEffect

import _ from 'lodash' import { useEffect } from 'react'  const useLocalStorageEffect = (callback, deps = []) => { if (!_.isFunction(callback)) { throw new Error('Callback in useLocalStorageEffect is not a function') }  if (!_.isArray(deps)) { throw new Error('Depends in useLocalStorageEffect is not a Array') }  const storageListener = (event) => { if (_.size(deps) > 0 && deps.includes(_.get(event, 'key'))) { return callback( _.get(event, 'key', ''), JSON.parse(_.get(event, 'newValue', '')), JSON.parse(_.get(event, 'oldValue', '')) ) }  if (_.isArray(deps) && _.size(deps) === 0) { return callback( _.get(event, 'key', ''), JSON.parse(_.get(event, 'newValue', '')), JSON.parse(_.get(event, 'oldValue', '')) ) } }  useEffect(() => { window.addEventListener('storage', storageListener, false)  return () => window.removeEventListener('storage', storageListener) }, []) }  export default useLocalStorageEffect

useLocalStorageEffect принимает два аргумента:

  • Функцию обработчик, которая принимает в себя 3 аргумента(ключ, новое значения, старое значение)

  • Массив который содержит ключи в localStorage, при изменении значений которых будет вызываться функция обработчик


ссылка на оригинал статьи https://habr.com/ru/articles/733194/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *