[RN] AsyncStorage 정리

fejigu·2023년 7월 27일
1

React Native

목록 보기
11/11
post-thumbnail


✔️ 무엇인지

→ 지금 내가 사용하고 있는, React Native Expo CLI 앱에서 사용하는 AsyncStorage웹 브라우저의 localStorage와 유사한 기능을 제공하는 비동기적인 로컬 데이터 저장소이다.


✔️ 언제,어떻게 사용하는지

→ AsyncStorage는 앱 내에서 작은 데이터를 장기간 저장하고 관리하는 데 사용된다. (like 쿠키) 일반적으로 앱의 세션 상태를 유지하거나 오프라인 상태에서 데이터를 보존하는 데 활용할 것이다.

"그럼 AsyncStorage는 어떤 식으로 데이터를 저장할까?"
사실 이 부분은 제대로 알지 못하고,AsyncStorage를 무분별하게 사용했다가 코드를 수정하느라 고생을 했기에 이번에 잘 정리해두려고 한다.

1) AsyncStorage는 'key-value 쌍'으로 데이터를 저장한다.
2) 그리고 이러한 데이터는 '문자열 형태'로 저장된다.
3) 그러니 객체나 배열을 AsyncStorage에 저장하려면,
JSON.stringify()를 사용해서 문자열로 변환 후 저장하고,
JSON.parse()를 사용해서 객체나 배열로 변환해야한다.

1) AsyncStorag 사용하기

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;

2) Typescript 적용하기

→ 현재 진행 중인 프로젝트에서는 타입스크립트를 사용하니, 타입스크립트까지 적용해보자.

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;

3) Recoil 상태관리와 함께 사용하기

→ 마지막으로, 전역 상태 관리를 위해 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로 저장해서 관리할 지 다시 한번 체크를 해야할 것 같다. !

profile
console.log(frontendjigu( ☕️, 📱); // true

0개의 댓글