React Query + Recoil 적용기(2)

jiseong·2022년 3월 3일
3

T I Learned

목록 보기
186/291
post-thumbnail

비동기 api 코드는 react-query를 사용하여 처리하다보니 이제는 굳이 redux saga를 쓸 필요성이 없어지게 되었다. 그래서 보다 간편하게 사용할 수 있고 atom effects를 활용하여 쉽게 localStorage에서 상태를 유지할 수 있는 점에서 recoil을 선택하게 되었다.

우선, 기존의 토글을 사용하여 테마를 바꾸는 코드를 redux → recoil로 변경해볼 예정이다.

기존의 코드는 아래와 같이 작성되어 있으며 localstorage와 해당 상태를 동기화 해주는 코드를 추가적으로 작성해야 했다.

const SET_MODE = 'common/SET_MODE' as const;

export const setMode = createAction(SET_MODE);

const initialState = {
  mode: getInitTheme(),
};

const common = handleActions(
  {
    [SET_MODE]: (state) => {
      setItem('theme', !state.mode); // localstorage 관리하는 코드

      return {
        ...state,
        mode: !state.mode,
      };
    },
  },
  initialState,
);

export default common;

recoil로 작성하게 되면 아래 코드만 작성해주고 루트 컴포넌트에 RecoilRoot만 추가해주면 된다.

export const themeState = atom({
  key: 'themeState',
  default: true,
});

여기서 해당 상태를 localStorage와 같이 사용하기위해서는 조금 더 코드를 작성해주면 된다. setSelf 함수는 로컬스토리지에서 값을 불러와 초기값을 지정해주는 함수이고 onSet함수가 해당 atom값이 변경될 때마다 로컬스토리지와 atom 값을 동기화해주는 역할을 한다.

const localStorageEffect =
  <T>(key: string) =>
  ({ setSelf, onSet }: any) => {
    const savedValue = getItem(key);

    // Callbacks to set or reset the value of the atom.
    if (savedValue != null) {
      setSelf(savedValue);
    }

    // Subscribe to changes in the atom value.
    onSet((newValue: T, _: any, isReset: boolean): void => {
      isReset ? removeState(key) : setItem(key, newValue);
    });
  };

이제 기존의 atom에 위에서 작성한 함수를 effects에 추가해주기만 하면 된다.

export const themeState = atom({
key: 'themeState',
default: true,
effects: [localStorageEffect(KEY)],
});

나머지 전역상태를 나타낼 코드도 설정하는 부분이 거의 비슷해서 크게 차이 없이 바꿀 수 있었다.

음... recoil을 사용하면서 느꼈던 장점은 사용하기 위해 작성해야 할 코드가 redux에 비해 정말 적었다는 점과 context와 비교하면 렌더링 최적화에 대한 고민이 적어졌다는 점이다.

끝~

0개의 댓글