Skip to main content

useSessionStorage

React v18부터 지원하는 useSyncExternalStore 을 활용해 세션 스토리지 내의 특정 key 데이터를 구독하고, 구독 중인 데이터에 변화가 있을 시 이를 동기화해주는 커스텀 훅입니다.

세션 스토리지에 구독하고자 하는 key가 없을 경우 반환할 initialValue로 초기값을 설정할 수 있습니다. 또한, 서버 사이드 렌더링(SSR)의 경우 세션 스토리지가 동작하지 않기 때문에 initialValue가 반환됩니다.

setState는 값 자체를 넘길 수 있으며, 함수도 넘길 수 있습니다. 함수로 활용 시에 인자로 state를 가져올 수 있습니다.

const { state, setState, removeState } = useSessionStorage<number[]>({
key: 'test',
initialValue: [1, 2],
});

setState([1, 2, 3]);
setState(state => [...state, 3]);

initialValue를 넘겨주면 더욱 명확한 타입 추론이 가능합니다.

const { state, setState } = useSessionStorage<number[]>({
key: 'test',
});

state; // number[] | null
setState(state => {
state; // number[] | null
});
const { state, setState } = useSessionStorage<number[]>({
key: 'test',
initialValue: [],
});

state; // number[]
setState(state => {
state; // number[]
});

Code

🔗 실제 구현 코드 확인

Interface

typescript
interface UseSessionStorageWithoutInitialValueProps {
key: string;
}

interface UseSessionStorageWithInitialValueProps<T> {
key: string;
initialValue: T | (() => T);
}

type UseSessionStorageProps<T> =
| UseSessionStorageWithoutInitialValueProps
| UseSessionStorageWithInitialValueProps<T>;
// 함수 오버로딩
function useSessionStorage<T>({
key,
initialValue,
}: UseSessionStorageWithInitialValueProps<T>): {
state: T;
setState: Dispatch<SetStateAction<T>>;
removeState: () => void;
};

function useSessionStorage<T = unknown>({
key,
}: UseSessionStorageWithoutInitialValueProps): {
state: T | null;
setState: Dispatch<SetStateAction<T | null>>;
removeState: () => void;
};

Usage

typescript
import { useSessionStorage } from '@modern-kit/react';

const Example = () => {
const { state, setState, removeState } = useSessionStorage<string>({
key: 'test',
initialValue: 'default',
});

return (
<div>
<p>개발자 도구에서 세션 스토리지를 확인해보세요!</p>
<p>state: {state}</p>
<button onClick={() => setState('foo')}>
{`세션 스토리지 "test"key에 "foo"데이터 저장`}
</button>
<button onClick={() => setState('bar')}>
{`세션 스토리지 "test"key에 "bar"데이터 저장`}
</button>
<button onClick={() => removeState()}>
{`세션 스토리지 "test"key 제거`}
</button>
</div>
);
};

Example

개발자 도구에서 세션 스토리지를 확인해보세요!

state: default