AsyncStorage는 애플리케이션의 간단한 데이터를 비동기적으로 저장하고 불러오는데 사용된다.
1) 재사용성
AsyncStorage wrapper 함수를 정의해두면,
앱 전체에서 동일한 방식으로 AsyncStorage에 접근할 수 있다.
이는 코드의 중복을 줄이고 유지 보수를 용이하게 한다.
2) 오류 처리
각 함수 내에서 try-catch 문을 사용하여 오류 처리를 하고 있다.
이렇게 하면 AsyncStorage의 메소드가 에러를 발생시킬 때마다
개별적으로 오류 처리를 할 필요가 없어집니다.
3) 데이터 형식 통일
setAsyncData 함수에서는 저장하려는 값을 문자열로 변환한 후 저장하고,
getAsyncData에서는 가져온 데이터를 다시 원래의 형태로 파싱한다.
이런 방식은 데이터의 형식을 일관되게 관리할 수 있게 해준다.
4) 타입 안전성
TypeScript 환경에서 작업할 때, Generic을 활용하는 것으로 타입 안전성(type safety)을 보장받을 수 있다.
Generic을 사용하는 이유는 호출 시점에 T가 결정되어 다양한 타입에 대해 동작할 수 있게 해주기 때문에 유연성을 높여준다.
(getAsyncData 참조)
=> 따라서 AsyncStorage에 직접 접근하기보다
위와 같이 래퍼(wrapper) 함수를 만들어 사용하는 것이 좋은 패턴이라고 한다.
// 데이터 저장
export const setAsyncData = async (key: string, value: unknown) => {
try {
const stringValue = JSON.stringify(value);
await AsyncStorage.setItem(key, stringValue);
return true;
} catch (error) {
reactotron.log!(error);
return false;
}
};
// 데이터 불러오기
export const getAsyncData = async <T>(key: string): Promise<T | null> => {
try {
const value = await AsyncStorage.getItem(key);
if (value !== null) {
const data = JSON.parse(value) as T;
return data;
}
} catch (error) {
reactotron.log!(error);
}
return null;
};
// 데이터 삭제
export const removeAsyncData = async (key: string) => {
try {
await AsyncStorage.removeItem(key);
} catch (error) {
reactotron.log!(error);
}
};
변수를 할당하여 로그를 찍어볼 수도 있다.
setAsyncData("저장할 키", 저장할 값);
getAsyncData<string>("불러올 키");
removeAsyncData("삭제할 키");
먼저 AsyncStorage에 객체로 값을 관리할 때의 장점과 단점을 알아보자면,
장점
1) 구조화된 데이터 관리
객체 형태로 데이터를 저장하면 구조화된 방식으로 데이터를 관리할 수 있다.
즉, 키-값 쌍의 형태로 정보를 저장하므로 각각의 값에 이름을 부여할 수 있어서 코드가 더욱 명확해진다.
2) 다양한 타입의 값 저장 가능
JavaScript 객체는 다양한 타입의 값을 속성으로 가질 수 있습니다.
숫자, 문자열, 배열 등 다양한 타입의 값을 한 번에 저장하고 불러올 수 있다는 점에서 유용하다.
단점
1) 변환 과정 필요
AsyncStorage에서 직접적으로 지원하는 값은 문자열만 가능하기 때문에 객체를 저장하거나 불러올 때마다 JSON 형식으로 변환해야 한다(JSON.stringify, JSON.parse).
2) 부분 수정 어려움
AsyncStorage는 전체 객체를 가져와서 수정 후 다시 전체 객체를 저장해야 하는 방식이기 때문에 개별 속성을 수정하기 어렵다.
성능 저하 문제를 일으킬 가능성이 있어서 복잡한 구조나 큰 크기의 데이터, 자주 변경되는 경우 등엔 AsyncStorage보다 서버와 통신하여 서버에서 상태 관리하는 것이 좋습니다.
개별 속성을 수정하기에 어렵다는 것에 동감하며,
그럼에도 불구하고 AsyncStorage에 객체로 저장한 값을 수정하고 싶다면
아래 코드를 참고해보자
참고로 본인은 구현해놓고 AsyncStorage를 너무 복잡하게 관리하는 것 같아 객체로 저장하는 코드는 버렸다 ㅎㅅㅎ
// 데이터 수정
export const updateAsyncData = async (key: string, updatedValue: unknown) => {
try {
// 1. 저장된 값을 불러옵니다.
const existingValue = await getAsyncData(key);
if (existingValue !== null) {
// 2. 원하는 값을 수정합니다.
const updatedData: unknown = {
...(existingValue as object), // 기존 값이 객체여야 함
...(updatedValue as object), // 업데이트할 값도 객체여야 함
};
// 3. 수정된 값을 다시 저장합니다.
await setAsyncData(key, updatedData);
reactotron.log!("값이 업데이트되었습니다.");
} else {
reactotron.log!("값이 존재하지 않습니다.");
}
} catch (error) {
reactotron.log!("데이터를 업데이트하는 중에 오류가 발생했습니다.", error);
}
};