⚡ 전역 상태 Web Storage에 저장하기
리액트에서 전역 상태 관리를 위해 Recoil을 도입해서 사용했습니다.
여러 컴포넌트에서 사용하는 서버 데이터를 전역으로 저장했지만
새로고침을 하게 되면 데이터가 증발하고 다시 API를 호출해서 웹 스토리지에 데이터를 저장하는 방법을 사용했습니다.
그럼 Recoil Effects를 이용해 Web Storage인 Local Storage와 Session Storage에
자동으로 연동하는 방법을 소개합니다.
⚡ Web Storage
Web Storage는 웹 브라우저에 직접 데이터를 저장할 수 있는 기능으로
Local Storage와 Session Storage 두 가지 종류가 있습니다.
쿠키는 4KB의 적은 용량이지만 웹 스토리지는 5MB라는 넉넉한 용량을 사용할 수 있습니다.
📌 Local Storage
- 브라우저를 종료해도 데이터 보존
- 캐시 초기화, 데이터 삭제가 아니면 영구 보존
- 변동성이 크게 없는 데이터 저장하기 용이, ex) 자동로그인 Token
📌 Session Storage
- 탭이나 창을 닫으면 데이터 증발
- 같은 URL이어도 다른 탭이면 공유 불가능
- 변동성이 있는 데이터를 가볍게 저장하여 부하를 덜어줄 수 있는 용도로 사용
📌 Storage 사용법
두 저장소는 동일한 Storage API를 이용하기 때문에 개념만 다를 뿐 사용법이 완전히 같습니다.
저장되는 데이터는 Key : Value
쌍으로 이루어져 있으며 Value에는 문자열만 저장할 수 있습니다.
사용가능한 메소드는 다음과 같습니다.
length()
: 데이터 길이 반환getItem(key)
: 키에 해당하는 데이터를 반환setItem(key, value)
: 키에 대한 값을 저장removeItem(key)
: 키에 해당하는 데이터 삭제clear()
: 스토리지에 저장된 모든 데이터 삭제
스토리지 별 메소드를 사용할 때는 다음과 같이 사용할 수 있습니다.
// 로컬 스토리지
localStorage.clear();
// 세션 스토리지
sessionStorage.clear();
⚡ Recoil Effects로 스토리지 연동
Atom의 Effects는 공식문서에서 아래와 같이 소개하고 있습니다.
Atom Effects는 부수효과를 관리하고 Recoil의 atom을 초기화 또는 동기화하기 위한 API입니다.
말 그대로 useEffect
와 같이 atom
내에서 부수효과(Side Effect
)를 관리하기 위해 사용할 수 있습니다.
export const storageState = atom<any>({
key: "storageState",
default: undefined,
effects: [
({ setSelf, onSet }) => {
const savedData = sessionStorage.getItem("item");
// setSelf: atom 값을 설정 혹은 재설정
if (savedData) setSelf(JSON.parse(savedData));
// atom이 변화가 감지될 때 작동, Storage에 데이터 저장
// setSelf에 의해서는 작동하지 않음
onSet((newValue, _, isReset) => {
isReset
? sessionStorage.removeItem("item")
: sessionStorage.setItem("item", JSON.stringify(newValue));
});
}
]
});
간단하게 effects
를 이용하여 Storage
와 atom
을 연동했습니다.
주요 함수는 다음과 같습니다.
setSelf
: atom 값을 설정합니다. 주로 Storage에 있는 데이터를 atom에 넣어줄 때 사용합니다.onSet
: atom의 변화를 감지해 Storage에 데이터를 저장합니다.
주의사항으로는 데이터를 저장할 땐 문자열만 저장이 가능하기 때문에
Json 데이터를 저장할 땐 JSON.stringify()
를 이용해 문자열로 변환해주고,
atom에 Storage 데이터를 저장할 땐 JSON.parse()
를 이용해 문자열을 Json 형식으로 변환해줘야 합니다.
const getFetchData = () => {
console.log("API Call");
return fetch("https://jsonplaceholder.typicode.com/posts/1")
.then((response) => response.json())
.then((data) => data);
};
export default function App() {
const [data, setData] = useRecoilState(storageState);
useEffect(() => {
if (!data) getFetchData().then(setData);
},[data]);
return (
<div className="App">
<h1>{JSON.stringify(data)}</h1>
</div>
);
}
간단한 예제를 작성해봤습니다.
- Storage에 데이터가 없을 때
- atom 데이터가 없기 때문에 데이터 fetching
- atom에 저장
- sessionStorage 저장
- Storage에 데이터가 있을 때
- effects에 의해 sessionStorage 데이터 atom에 저장
- atom 데이터가 있기 때문에 API 호출 안함
- 새로고침 시 atom의 데이터가 날라가도 스토리지 데이터를 다시 atom에 저장
⚡ Web Storage 데이터 확인
저장된 스토리지 데이터는
개발자 도구 > Application > Session Storage/Local Storage에서 확인할 수 있습니다.
'React' 카테고리의 다른 글
[React] react-query, 리액트 쿼리를 사용해야 하는 이유 (2) | 2023.04.16 |
---|---|
[React] Suspense을 사용해 선언적으로 로딩 화면 구현하기 (4) | 2023.03.23 |
[React/TypeScript] Debounce, 일정 시간동안 발생한 이벤트 중 마지막만 실행 (0) | 2023.03.08 |
[React] input 한 글자 입력 시 focus out 되는 현상 (0) | 2023.03.02 |
[React + Craco + TS] Alias 절대경로 + 폴더 index 절대경로 설정 방법 (0) | 2023.02.14 |
댓글