Last active
July 28, 2021 00:46
-
-
Save ynifamily3/dbd9376fee15a7de52a15d3141b1d3b2 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import localItemContext, { | |
setLocalItemValue, | |
} from "#/context/localItemContext"; | |
import { useReactiveVar } from "@apollo/client"; | |
import { useCallback, useEffect } from "react"; | |
type UseReactiveLocalItemReturnType = <V>( | |
key: string, | |
defaultValue?: V, | |
) => [V, (value: V | ((prevState: V) => V) | null) => void]; | |
const rawGetLocalItem = <T>(key: string) => { | |
const raw = localStorage.getItem(key); | |
const value = | |
raw !== null && raw !== undefined ? (JSON.parse(raw) as T) : null; | |
return value; | |
}; | |
const useReactiveLocalItem: UseReactiveLocalItemReturnType = <T>( | |
key: string, | |
defaultValue?: T, | |
) => { | |
const localItem = useReactiveVar(localItemContext); | |
const raw = localItem[key]; | |
const value = | |
raw !== null && raw !== undefined ? (JSON.parse(raw) as T) : defaultValue; | |
const setValue = useCallback( | |
(valueOrSetterFunction: T | ((prevState: T) => T) | null) => { | |
try { | |
if (typeof valueOrSetterFunction === "function") { | |
const setterFn = valueOrSetterFunction as (state: T) => T; | |
const newValue = setterFn(rawGetLocalItem(key) as T); | |
if (newValue === null) { | |
localStorage.removeItem(key); | |
} else { | |
localStorage.setItem(key, JSON.stringify(newValue)); | |
setLocalItemValue(key, JSON.stringify(newValue)); | |
} | |
return; | |
} | |
if (valueOrSetterFunction === null) { | |
localStorage.removeItem(key); | |
} else { | |
localStorage.setItem(key, JSON.stringify(valueOrSetterFunction)); | |
} | |
setLocalItemValue(key, JSON.stringify(valueOrSetterFunction)); | |
} catch (e) { | |
console.error( | |
"setValue LocalStorage Exception:", | |
e, | |
key, | |
valueOrSetterFunction, | |
); | |
} | |
}, | |
[key], | |
); | |
if (value === undefined) { | |
throw new Error( | |
"[reacviteLocalItem] 로컬스토리지 값이 잘못되었습니다. (아니라면 기본값을 제공해 주세요)", | |
); | |
} | |
if ((raw === null || raw === undefined) && defaultValue !== undefined) { | |
setValue(defaultValue); | |
} | |
// 외부 브라우저의 localStorage 변경사항 수신 | |
useEffect(() => { | |
const handler = () => { | |
const raw = localStorage.getItem(key); | |
const value = | |
raw !== null && raw !== undefined | |
? (JSON.parse(raw) as T) | |
: defaultValue; | |
if (value === undefined) { | |
throw new Error( | |
"[reacviteLocalItem] 로컬스토리지 값이 잘못되었습니다. (아니라면 기본값을 제공해 주세요)", | |
); | |
} | |
if ((raw === null || raw === undefined) && defaultValue !== undefined) { | |
setLocalItemValue(key, JSON.stringify(defaultValue)); | |
} else { | |
setLocalItemValue(key, JSON.stringify(value)); | |
} | |
}; | |
window.addEventListener("storage", handler); | |
return () => { | |
window.removeEventListener("storage", handler); | |
}; | |
}, [key, defaultValue]); | |
return [value, setValue]; | |
}; | |
export { useReactiveLocalItem }; |
차라리 현 상태를 localStorage에서 그냥 raw하게 긁어와서
해결하든지 해야지
어휴
해결함
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
ref로 잡아두기