[React] Recoil Effects & local storage 사용하기

thousand_yj·2023년 7월 26일
0

Willing 프로젝트

목록 보기
15/18

React에서 local storage 사용하기

일반적으로 useEffect Hook을 사용하여 맨 처음 로컬스토리지에 값이 저장되어 있는 경우 그 값을 사용하고, 아니면 초기값으로 셋팅해주면 된다. 나는 현재 상태 관리 방식으로 Recoil을 사용하고 있는데, Recoil Effects 공식문서를 보니 effects를 사용하도록 권장하더라.

Compared to React Effects (React Effects와 비교)

Atom Effects는 대부분의 경우 리액트의 useEffect()로 대체될 수 있습니다. 그러나 atom의 집합은 리액트 컨텍스트의 외부에서 생성되며, 특히 동적으로 생성된 atom의 경우 리액트 컴포넌트 내에서 효과를 관리하기 어려울 수 있습니다. 또한 초기 atom 값을 초기화하거나 서버 사이드 렌더링(SSR)과 함께 사용될 수도 없습니다. atom effects를 사용하는 것은 effects와 atom 정의를 함께 배치하게 합니다.

따라서 공식 문서의 설명에 맞춰 localStorage에 값을 저장할 수 있도록 코드를 작성했다.

const localStorageEffect = (key:string) => ({setSelf, onSet}: any) => {
  const savedValue = localStorage.getItem(key)
  // setSelf : Callbacks to set or reset the value of the atom.
  if (savedValue != null) {
    setSelf(JSON.parse(savedValue));
  }
  // onSet : Subscribe to changes in the atom value.
  onSet((newValue:any, _:any, isReset:any) => {
    isReset
      ? localStorage.removeItem(key)
      : localStorage.setItem(key, JSON.stringify(newValue));
  });
};
  • setSelf : Callbacks to set or reset the value of the atom. 즉 atom의 값을 설정/재설정할 때 사용
  • onSet : Subscribe to changes in the atom value. atom 값의 변화를 구독 (useState와 비슷하다)

위와 같이 함수를 작성해준 다음 atom을 정의해주는 부분에 effects를 추가하면 된다.

/* 선택된 날짜 State */
// 서비스 시작 화면은 오늘날짜, 날짜 기준 수정 가능
const today = new Date();
export const selectedDateState = atom<Date>({
  key: "selectedDateState",
  default: today,
  effects: [localStorageEffect('selected_date')]
});

effects: [localStorageEffect('selected_date')] 이 부분이 로컬스토리지에 전달된 문자열을 키 값으로 데이터를 저장하도록 한다.

의문. default 값이 분명 잘 있는데 왜 local Storage에는 저장되어 있지 않은가?

useEffect()를 사용해서 해당 recoil의 set함수를 호출하기 전까지는 값을 호출해보면 제대로 값이 들어가있으나 local storage에서는 찾아볼 수 없다. 흠...

일단 set함수를 사용하여 예전 상태에 기반한 업데이트를 하면 default 값이 잘 들어가 있으니 일단은 크게 코드를 바꿀 건 없어서 좋았다.

effects를 사용한다고 useRecoilState()를 사용하는 방법이 달라지는 것은 아니다

주의! JSON의 자료형

Local storage에 데이터를 입출력할 때 사용되는 포맷은 JSON이다.

JSON에서 지원하는 자료형

  • 수(Number)
  • 문자열(String): 0개 이상의 유니코드 문자들의 연속. 문자열은 큰 따옴표(“)로 구분.
  • 참/거짓(Boolean): true 또는 false 값
  • 배열(Array): 0 이상의 임의의 종류의 값으로 이루어진 순서가 있는 리스트. 대괄호로 나타내며 요소는 쉼표로 구분한다.
  • 객체(Object): 순서가 없는 이름/값 쌍의 집합으로, 이름(키)이 문자열이다.
  • null: 빈 값

따라서 나는 JS에서 지원하는 Date객체를 사용해서 데이터를 넣었음에도 데이터를 빼보면 dateString으로 실제로는 문자열 데이터가 리턴된다. 따라서 실제로 사용할 때는 new Date()로 감싸서 Date 객체로 만들어줘야 Date 자료형으로 잘 작동한다.

JSON에서 넣고 뺄 때 자료형이 바뀌니 주의하자! (이건 Backend와 통신할 때도 똑같다.)

profile
함께 일하고 싶은 개발자가 되기 위해 노력합니다. 코딩테스트 관련 공부 및 이야기는 티스토리에도 업로드되어 있습니다.

0개의 댓글