본문 바로가기
개발/ReactNative

[ReactNative] expo 메모장 앱만들기 (2)

by 그레이웅 2022. 10. 23. 00:12
반응형

지난 포스팅

 

2022.10.21 - [개발/ReactNative] - [ReactNative] expo 메모장 앱만들기 (1)

 

[ReactNative] expo 메모장 앱만들기 (1)

메모장 앱 만들기 (1) ReactNative와 expo를 이용하여 메모장 앱을 만들어보겠다. 기본적인 설치와 설정은 이전 포스팅을 참고하면된다. 2022.10.20 - [개발/ReactNative] - [ReactNative] expo 설치하기 [ReactN..

ijw9209.tistory.com

 

 

저번 포스팅에 이어 메모장 앱 만들기를 이어가도록 하겠다.

저번 포스팅에서는 메모장 앱을 실행하는 방법과, 엔터효과를 구현하는 것까지 구현하였다.

 

 

 

1. 저장, 불러오기 기능 만들기

 앱 내 저장기능을 만드는 건 AsyncStorage를 사용하여 저장할 수 있다.

 

https://docs.expo.dev/versions/latest/sdk/async-storage/

 

AsyncStorage - Expo Documentation

Expo is an open-source platform for making universal native apps for Android, iOS, and the web with JavaScript and React.

docs.expo.dev

링크의 문서에도 잘정리가 되어있다.

 

"An asynchronous, unencrypted, persistent, key-value storage API."

키 벨류를 사용한, 암호화 되지않은 비동기식 API이다.

 

AsyncStorage를 사용하려면 다음과 같은 명령어를 설치해준다.

 

npx expo install @react-native-async-storage/async-storage

 

 

사용법

 

사용 방법은 공식문서에 나와있는데 데이터를 저장할 때 JSON.stringfy() 데이터를 불러올 때 JSON.parse()로 불러올 수 있다. JSON형태에 string을 저장한다고 설명되어 있다.

 

다음 예제와 같이 저장할때는 storeData 함수처럼, 단순 string 형태를 저장할 땐 저렇게 사용하지만 객체도 저장이 가능하다. getData() 함수도 마찬가지로 키 값을 이용하여 불러오게 된다.

async, await은 비동기 통신에 사용되는 es7 문법인데 비동기 작업이 완료될때 까지 await 기다려주는 명령어이다.

//import
import AsyncStorage from '@react-native-async-storage/async-storage';


//데이터 저장
const storeData = async (value) => {
  try {
  						//key, value
    await AsyncStorage.setItem('@storage_Key', value)
  } catch (e) {
    // saving error
  }
}

//데이터 불러오기
const getData = async () => {
  try {							//key
    const value = await AsyncStorage.getItem('@storage_Key')
    if(value !== null) {
      // value previously stored
    }
  } catch(e) {
    // error reading value
  }
}

 

 

코드 변경

 

App.js 전체

 

import React , { useState,  } from 'react';
import { StatusBar } from 'expo-status-bar';
import { StyleSheet, Text, View, SafeAreaView , Button, TextInput } from 'react-native';
import AsyncStorage from '@react-native-async-storage/async-storage';

export default function App() {

  const [ txt , setTxt ] = useState("안녕하세요. ");
 
 
  const saveData = async (value) => {
    try {
      await AsyncStorage.setItem('memoData', value)
      console.log('저장');
    } catch (e) {
      // saving error
    }
  }

  const loadData = async () => {
    try {
      const value = await AsyncStorage.getItem('memoData')
      if(value !== null) {
        // value previously stored
        setTxt(value)
      }
    } catch(e) {
      // error reading value
    }
  }
  

  return (
    <View style={{flex : 1, backgroundColor :'#fc0'}}>
    <SafeAreaView style={{flex: 1,  }}>
      {/* <StatusBar style='auto'/> */}
      <View style={{padding : 20, flexDirection : 'row', alignItems : 'center', justifyContent : 'space-between'}}>
        
        <Button title="저장" onPress={() => saveData(txt)}></Button>
        <Text style={{textAlign : 'center' , fontSize : 18}}>메모장</Text>
        <Button title="불러오기" onPress={() => loadData()}></Button>
      </View>
      <View style={{backgroundColor : '#eeeeee', flex :1, padding : 20}}>
        <TextInput 
        value={txt} 
        onChangeText={ txt => setTxt(txt)}
        // 줄바꿈 가능
        multiline
        
        ></TextInput>
      </View>
    </SafeAreaView>
    </View>
  );
}

 

변경내용을 설명하자면 saveData()loadData() 함수를 추가하였다. saveData()는 말 그대로 저장을 하고 loadData()는 저장한 내용을 불러오는 함수이다. 값이 null이 아니면 현재 state에 setTxT라는 변수로 담기게 된다.

모바일로는 개발자 도구가 없기 때문에 저장이란 버튼을 누르면 console.log('저장') 저장이라는 내용이 터미널로 보이게 된다.

 

 const saveData = async (value) => {
    try {
      await AsyncStorage.setItem('memoData', value)
      console.log('저장');
    } catch (e) {
      // saving error
    }
  }

  const loadData = async () => {
    try {
      const value = await AsyncStorage.getItem('memoData')
      if(value !== null) {
        // value previously stored
        setTxt(value)
      }
    } catch(e) {
      // error reading value
    }
  }

 

렌더링 부분에는 버튼에 onPress 버튼이 눌렸을 때에 saveData() 함수와 loadData() 함수를 연결해 주었다.

() =>라는 표시는 onPress속성이 실행되었을 때 함수를 실행하라는 명령이다.

 <View style={{padding : 20, flexDirection : 'row', alignItems : 'center', justifyContent : 'space-between'}}>
     <Button title="저장" onPress={() => saveData(txt)}></Button>
     <Text style={{textAlign : 'center' , fontSize : 18}}>메모장</Text>
     <Button title="불러오기" onPress={() => loadData()}></Button>
 </View>

 

실행화면 

 

저장 테스트라는 텍스트를 쓰고 저장을 하였다.

 

터미널에는 저장이라는 콘솔이 찍히게 된다. 내용을 지우고 지웠습니다 라는 글씨로 바꾼 다음 불러오기 버튼을 누른다.

 

 

불러오기 버튼을 누르면 텍스트의 글씨가 다시 저장 테스트라는 텍스트로 바뀌게 된다.

 


2. useEffect 사용하기

 

import React , { useState, useEffect } from 'react';

 

  useEffect(() => {
    console.log('프로그램시작');
    loadData();
  }, [])

다음과 같이 useEffect를 import 하고 함수를 추가해준다. 

useEffect는 React hook 함수형 컴포넌트에서 사용하는 함수인데 컴포넌트가 마운트(생성)될 때나 언마운트(제거)될 때 사용되고, state의 상태 변화가 있을 때 사용할 수 있다.

useEffect 함수의 마지막 부분에 [] 형태를 넣어주면 컴포넌트가 실행되고 바로 useEffect 함수가 실행된다.

지금은 메모장에 저장한 데이터를 프로그램이 시작되면 바로 로드하여 불러오게 된다.

 

 

App.js

이렇게 useEffect() 함수를 추가해 주었다.

import React , { useState, useEffect } from 'react';
import { StatusBar } from 'expo-status-bar';
import { StyleSheet, Text, View, SafeAreaView , Button, TextInput } from 'react-native';
import AsyncStorage from '@react-native-async-storage/async-storage';

export default function App() {

  const [ txt , setTxt ] = useState("안녕하세요. ");

  useEffect(() => {
    console.log('프로그램시작');
    loadData();
  }, [])


  const saveData = async (value) => {
    try {
      await AsyncStorage.setItem('memoData', value)
      console.log('저장');
    } catch (e) {
      // saving error
    }
  }

  const loadData = async () => {
    try {
      const value = await AsyncStorage.getItem('memoData')
      if(value !== null) {
        // value previously stored
        setTxt(value)
      }
    } catch(e) {
      // error reading value
    }
  }
  

  return (
    <View style={{flex : 1, backgroundColor :'#fc0'}}>
    <SafeAreaView style={{flex: 1,  }}>
      {/* <StatusBar style='auto'/> */}
      <View style={{padding : 20, flexDirection : 'row', alignItems : 'center', justifyContent : 'space-between'}}>
        <Button title="저장" onPress={() => saveData(txt)}></Button>
        <Text style={{textAlign : 'center' , fontSize : 18}}>메모장</Text>
        <Button title="불러오기" onPress={() => loadData()}></Button>
      </View>
      <View style={{backgroundColor : '#eeeeee', flex :1, padding : 20}}>
        <TextInput 
        value={txt} 
        onChangeText={ txt => setTxt(txt)}
        // 줄바꿈 가능
        multiline
        
        ></TextInput>
      </View>
    </SafeAreaView>
    </View>
  );
}
반응형

댓글