본문으로 건너뛰기

useStorageState

localStorage 또는 sessionStorage에 상태를 저장하고 동기화할 수 있는 커스텀 React Hook입니다.

  • 페이지를 새로고침하거나 이동해도 상태가 유지됩니다.
  • 다른 탭이나 창에서 동일 키의 Storage 값이 변경되면 해당 변경 사항이 자동으로 상태에 반영됩니다.
  • 필요 시 refresh() 함수를 통해 수동으로 Storage 값을 다시 불러올 수 있습니다.
  • 초기값 저장 여부, 직렬화/역직렬화 함수도 유연하게 설정할 수 있습니다.

🔗 사용법

const [value, setValue, refresh] = useStorageState(key, initialValue, options);

📥 매개변수

이름타입설명
keystring저장소에 저장할 키
initialValueT값이 없을 때 사용할 초기값
optionsobject?선택값. 저장소 타입, 직렬화 함수, 자동 초기 저장 여부 등을 설정 가능

🔧 options 구조

필드타입설명
type'local' | 'session'사용할 저장소 타입 (localStorage 또는 sessionStorage) (기본: local)
autoInitboolean저장소에 값이 없을 경우 initialValue를 자동 저장할지 여부 (기본: true)
serializer(value: T) => string값을 문자열로 직렬화하는 함수 (기본: JSON.stringify)
deserializer(value: string) => T문자열을 원래 값으로 역직렬화하는 함수 (기본: JSON.parse)

🔁 반환값

[value, setValue, refresh]

인덱스이름타입설명
0valueT현재 상태값
1setValue(value: T | (prev: T) => T) => void상태를 업데이트하고 Storage에 저장
2refresh() => voidStorage의 최신 값을 수동으로 불러와 상태를 갱신

✅ 예시

기본 예시

import { useStorageState } from 'hookdle';

function ThemeToggle() {
const [theme, setTheme, refreshTheme] = useStorageState<'light' | 'dark'>('theme', 'light');

return (
<>
<button onClick={() => setTheme('light')}>라이트 모드</button>
<button onClick={() => setTheme('dark')}>다크 모드</button>
<button onClick={refreshTheme}>스토리지에서 새로고침</button>
<div>현재 테마: {theme}</div>
</>
);
}

localStorage를 외부에서 직접 수정한 경우

function ExternalStorageUpdate() {
const [value, , refresh] = useStorageState<number>('hi', 0);

return (
<button
onClick={() => {
localStorage.setItem('hi', JSON.stringify(10)); // 직접 수정
refresh(); // 수동으로 상태 갱신
}}
>
값 강제 동기화: {value}
</button>
);
}

localStorage.setItem(...)과 같이 훅 외부에서 Storage를 직접 수정한 경우, refresh()를 호출해야 상태가 반영됩니다.


💡 만약 이 훅이 없다면?

직접 localStorage에 접근해 상태를 초기화하고, useState, useEffect를 조합해야 합니다. 또한 탭 간 동기화나 수동 갱신 기능도 직접 구현해야 합니다!

function ThemeToggle() {
const [theme, setTheme] = useState<'light' | 'dark'>(() => {
const stored = localStorage.getItem('theme');
return stored ? (JSON.parse(stored) as 'light' | 'dark') : 'light';
});

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

// 다른 탭에서 변경 감지 (수동 구현 필요)
useEffect(() => {
const handler = (e: StorageEvent) => {
if (e.key === 'theme' && e.newValue) {
setTheme(JSON.parse(e.newValue));
}
};
window.addEventListener('storage', handler);
return () => window.removeEventListener('storage', handler);
}, []);

return (
<>
<button onClick={() => setTheme('light')}>라이트 모드</button>
<button onClick={() => setTheme('dark')}>다크 모드</button>
<div>현재 테마: {theme}</div>
</>
);
}

이처럼 useStorageState를 사용하면 저장소 관리, 직렬화, 동기화까지 간편하게 처리할 수 있습니다.