→ 지금 내가 사용하고 있는, React Native Expo CLI 앱에서 사용하는 AsyncStorage
는 웹 브라우저의 localStorage와 유사한 기능을 제공하는 비동기적인 로컬 데이터 저장소
이다.
→ AsyncStorage는 앱 내에서 작은 데이터를 장기간 저장하고 관리하는 데 사용된다. (like 쿠키) 일반적으로 앱의 세션 상태를 유지하거나 오프라인 상태에서 데이터를 보존하는 데 활용할 것이다.
"그럼 AsyncStorage는 어떤 식으로 데이터를 저장할까?"
사실 이 부분은 제대로 알지 못하고,AsyncStorage를 무분별하게 사용했다가 코드를 수정하느라 고생을 했기에 이번에 잘 정리해두려고 한다.
1) AsyncStorage는
'key-value 쌍'
으로 데이터를 저장한다.
2) 그리고 이러한 데이터는'문자열 형태'
로 저장된다.
3) 그러니 객체나 배열을 AsyncStorage에 저장하려면,
JSON.stringify()
를 사용해서 문자열로 변환 후 저장하고,
JSON.parse()
를 사용해서 객체나 배열로 변환해야한다.
import React, { useState, useEffect } from 'react';
import { View, Text, AsyncStorage, Button } from 'react-native';
const CartComponent = () => {
const [dataArray, setDataArray] = useState([
{ menu: 'galbi' },
{ price: '15$' },
]);
useEffect(() => {
// 컴포넌트가 마운트되었을 때 AsyncStorage에서 데이터를 로드한다.
loadData();
}, []);
const saveData = async () => {
try {
// 배열을 JSON 문자열로 변환하여 AsyncStorage에 저장한다.
const dataArrayString = JSON.stringify(dataArray);
await AsyncStorage.setItem('dataArray', dataArrayString);
console.log('데이터 저장 성공');
} catch (error) {
console.error('데이터 저장 오류', error);
}
};
const loadData = async () => {
try {
// AsyncStorage에서 데이터를 불러온다
const dataArrayString = await AsyncStorage.getItem('dataArray');
if (dataArrayString) {
// 불러온 JSON 문자열을 다시 배열로 변환하여 상태에 저장한다.
const parsedDataArray = JSON.parse(dataArrayString);
setDataArray(parsedDataArray);
}
} catch (error) {
console.error('데이터 불러오기 오류:', error);
}
};
return (
<View>
<Text>데이터:</Text>
{dataArray.map((item, index) => (
<Text key={index}>{JSON.stringify(item)}</Text>
))}
<Button title="데이터 저장" onPress={saveData} />
</View>
);
};
export default CartComponent;
→ 현재 진행 중인 프로젝트에서는 타입스크립트를 사용하니, 타입스크립트까지 적용해보자.
import React, { useState, useEffect } from 'react';
import { View, Text, AsyncStorage, Button } from 'react-native';
// 인터페이스를 정의한다.
interface CartItem {
menu: string;
price: string;
}
const CartComponent: React.FC = () => {
// 상태에 인터페이스를 적용하여 타입을 지정한다.
const [dataArray, setDataArray] = useState<CartItem[]>([
{ menu: 'galbi', price: '15$' },
]);
useEffect(() => {
// 컴포넌트가 마운트되었을 때 AsyncStorage에서 데이터를 로드한다.
loadData();
}, []);
const saveData = async () => {
try {
// 배열을 JSON 문자열로 변환하여 AsyncStorage에 저장한다.
const dataArrayString = JSON.stringify(dataArray);
await AsyncStorage.setItem('dataArray', dataArrayString);
console.log('데이터 저장 성공');
} catch (error) {
console.error('데이터 저장 오류', error);
}
};
const loadData = async () => {
try {
// AsyncStorage에서 데이터를 불러온다.
const dataArrayString = await AsyncStorage.getItem('dataArray');
if (dataArrayString) {
// 불러온 JSON 문자열을 다시 배열로 변환하여 상태에 저장한다.
const parsedDataArray: CartItem[] = JSON.parse(dataArrayString);
setDataArray(parsedDataArray);
}
} catch (error) {
console.error('데이터 불러오기 오류:', error);
}
};
return (
<View>
<Text>데이터:</Text>
{dataArray.map((item, index) => (
<Text key={index}>
메뉴: {item.menu}, 가격: {item.price}
</Text>
))}
<Button title="데이터 저장" onPress={saveData} />
</View>
);
};
export default CartComponent;
→ 마지막으로, 전역 상태 관리를 위해 Recoil도 사용하기로 했으니 Recoil까지 적용해보자. (이번 프로젝트에서 처음 사용하는 것이라, 작동 방식이 익숙치 않다..)
import React, { useEffect } from 'react';
import { View, Text, AsyncStorage, Button } from 'react-native';
import { atom, useRecoilState } from 'recoil';
// 인터페이스를 정의한다.
interface CartItem {
menu: string;
price: string;
}
// atom을 정의한다.
const dataArrayState = atom<CartItem[]>({
key: 'dataArrayState',
default: [{ menu: 'galbi', price: '15$' }],
});
const CartComponent: React.FC = () => {
// atom으로 상태를 읽고 변경한다.
const [dataArray, setDataArray] = useRecoilState(dataArrayState);
useEffect(() => {
// 컴포넌트가 마운트되었을 때 AsyncStorage에서 데이터를 로드한다.
loadData();
}, []);
const saveData = async () => {
try {
// 상태를 atom으로 변경한다.
await AsyncStorage.setItem('dataArray', JSON.stringify(dataArray));
console.log('데이터 저장 성공');
} catch (error) {
console.error('데이터 저장 오류', error);
}
};
const loadData = async () => {
try {
const dataArrayString = await AsyncStorage.getItem('dataArray');
if (dataArrayString) {
const parsedDataArray: CartItem[] = JSON.parse(dataArrayString);
setDataArray(parsedDataArray);
}
} catch (error) {
console.error('데이터 불러오기 오류:', error);
}
};
return (
<View>
<Text>데이터:</Text>
{dataArray.map((item, index) => (
<Text key={index}>
메뉴: {item.menu}, 가격: {item.price}
</Text>
))}
<Button title="데이터 저장" onPress={saveData} />
</View>
);
};
export default CartComponent;
→ 현재 프로젝트에서 회원가입 과정, 주문 프로세스 등 어떤 것을 AsyncStorage로 저장해서 관리할 지 다시 한번 체크를 해야할 것 같다. !