[React Native] 에러: Recoil과 AsyncStorage 동기화

한별·2023년 8월 30일

React Native

목록 보기
4/5

문제 상황

React Native를 이용해서 수강신청 연습 앱을 만들던 중, 문제가 발생했다.
로그인 화면에서 빠르게 메뉴 화면으로 넘어가는 경우,
헤더를 제외한 나머지 부분이 렌더링이 되지 않는 것이다. 😣
근데 열 받는 점은 로그인 화면에서 약 10초 기다린 후 페이지 이동 시에는 정상적으로 떴다...

문제 원인

문제 원인은 Recoil의 default값을 AsyncStorage에서 냅다 가져왔기 때문이었다.
AsyncStorage는 말 그대로 비동기적(Async)으로 동작하는데,
데이터를 가져오기도 전에 cartState를 사용하는 페이지(메뉴 화면)으로 이동했기 때문이다.
문제의 코드는 다음과 같다.

export const cartState = atom({
  key: 'cartState',
  default: storeData(newCart), // : AsyncStorage에 data를 저장하는 함수
});

해결

Recoil Atom Effects의 setSelf()를 이용해서 해결해주었다.
Recoil 공식 문서에서 알려준 방법이다.

지속되는 데이터를 비동기적으로 불러와야 할 때는, setSelf() 함수 내에서 Promise 를 사용하거나 데이터를 비동기적으로 호출할 수 있습니다

export const cartState = atom({
  key: 'cartState',
  default: [],
  effects: [
    async ({setSelf, onSet}) => {
      setSelf(await getData());
      onSet(newCart => {
        storeData(newCart);
      });
    },
  ],
});

추가로 onSet()을 이용하여 새로운 cartState가 set될 때마다 그 값을 AsyncStorage에 저장해주는 코드도 추가했다.

다음과 같은 코드를 통해 State와 AsyncStorage의 데이터를 동기화할 수 있다.

참고 자료

Atom Effects | Recoil

profile
글 잘 쓰고 싶어요

0개의 댓글