React
에서는 전역 데이터를 유지 및 보수, 관리하기 위해 recoil
이란 라이브러리를 사용하는 경우가 있습니다.
React Native
에서도 전역 데이터를 유지 및 보수, 관리하기 위해 recoil
라이브러리를 사용할 수 있습니다.
recoil 라이브러리 링크: https://recoiljs.org/ko/
브라우저 같은 경우, localStorage
라는 기능이 있어 recoil-persist
라는 NPM 패키지를 사용하여 로컬 환경에서 데이터를 저장할 수 있습니다.
recoil-persist 라이브러리 링크: https://www.npmjs.com/package/recoil-persist
하지만 모바일 에서는 localStorage
라는 기능이 없기 때문에 AsyncStorage
기능을 사용하여 로컬 환경에서 데이터를 저장할 수 있도록 구현해야 합니다.
React Native
공식문서에 나와 있는 AsyncStroage 기능은 사용 중단 되었으므로, Github Page로 설명되어 있는 AsyncStroage 페이지에서 패키지를 다운받아 사용해야 됩니다.
제 프로젝트 같은 경우, React Native 에서 TypeScript
언어를 사용하여 구현하고 있어 recoil을 사용하기 위한 state를 선언하는 코드 부분과 AsyncStroage 를 따로 구현하여 코드를 import 하여 사용했습니다.
해당 자료에 대해 찾아보기 위해 구글링을 해보다가 recoil-persist
NPM 패키지에 이슈 부분에서 확인을 하게 됐는데, React Native에서 recoil
과 AsyncStorage
를 연동하여 사용할 수 있는 방법에 대해 코멘트로 기록되어 있었습니다.
이슈 링크: https://github.com/polemius/recoil-persist/issues/45#issuecomment-1003399677
해당 코드를 제 프로젝트에 맞게 TypeScript
언어로 변환한 후, 적용하여 테스트 해봤습니다.
export const diaryState = atom<DiaryType>({
key: 'diaryState',
default: initialDiary,
});
export const diaryListState = atom<DiaryType[]>({
key: 'diaryListState',
default: [],
effects: [persistAtom('diaryListState')],
});
export const persistAtom =
<T>(key: string): AtomEffect<T> =>
({setSelf, onSet}) => {
setSelf(
AsyncStorage.getItem(key).then(
savedValue =>
savedValue != null ? JSON.parse(savedValue) : new DefaultValue(), // Abort initialization if no value was stored
),
);
// Subscribe to state changes and persist them to localForage
onSet((newValue, _, isReset) => {
isReset
? AsyncStorage.removeItem(key)
: AsyncStorage.setItem(key, JSON.stringify(newValue));
});
};
코드를 구현한 후, 앱을 실행해보니 stack은 정상적으로 보이나 view들은 보이지 않았습니다.
다시 이슈 페이지에서 확인해보니, 마지막 코멘트에 view가 보이지 않는 이슈에 대해서 해결하는 방법에 대해 나와 있는데
이는 recoil
라이브러리가 최신버전으로 업데이트 되면서 그에 따라 코드도 업데이트를 시킬 필요가 있었습니다.
이슈 코멘트와 공식문서에 나와 있는 코드들을 가지고 제 프로젝트 맞게 TypeScript
언어로 변환한 후, 적용하여 테스트 해봤습니다.
export const diaryState = atom<DiaryType>({
key: 'diaryState',
default: initialDiary,
});
export const diaryListState = atom<DiaryType[]>({
key: 'diaryListState',
default: [],
effects: [persistAtom('diaryListState')],
});
export const persistAtom =
<T>(key: string): AtomEffect<T> =>
({setSelf, onSet, trigger}) => {
const loadPersisted = async () => {
const savedValue = await AsyncStorage.getItem(key);
if (savedValue != null) {
setSelf(JSON.parse(savedValue));
}
};
// Asynchronously set the persisted data
if (trigger === 'get') {
loadPersisted();
}
// Subscribe to state changes and persist them to AsyncStorage
onSet((newValue, _, isReset) => {
isReset
? AsyncStorage.removeItem(key)
: AsyncStorage.setItem(key, JSON.stringify(newValue));
});
};
코드를 구현한 후, 앱을 실행해보니 view가 정상적으로 보이며, 로컬 스토리지에도 데이터가 정상적으로 저장이 되어 자동으로 데이터를 불러오는 것도 확인할 수 있었습니다! 😝