[React-Native]To-Do-App 저장하기
in Study on react_native
지금까지 따라 오시느라 수고하셨습니다. 이제 잘 작동되는 앱의 형태를 가지고 있는데요, 하지만 reload할 경우 작업한 내용을 기억하지 못하는 단점이 존재합니다.
오늘은 작업한 내용을 휴대폰 자체 저장소에 저장하고 불러올 수 있게 하는 작업을 해봅시다.
AsyncStorage
리액트 네이티브에서 제공하는 AsyncStorage 모듈은 Key-Value형태로 데이터를 저장하고, 이는 앱 어디에서나 접근이 가능합니다.
이는 웹을 사용할 때 로컬 저장소를 사용하는 것과 동일합니다.
To-Do-App에 저장해야 하는 데이터는 어떤 것이 있는지 알아보겠습니다.
할 일 목록
각 할 일의 완료여부
등 할 일에 관련된 정보입니다. 이러한 것들은 현재 state.todos에 저장되고 있습니다.
즉, 우리가 저장해야 할 데이터는 state의 todos값이니 이걸 저장하면 됩니다.
데이터를 저장하는 함수 만들기
//App.js
import React from 'react'
import { StyleSheet, Text, View, FlatList,AsyncStorage } from 'react-native'
import Header from './app/components/Header'
import SubTitle from './app/components/SubTitle'
import Input from './app/components/Input'
import TodoItem from './app/components/Todo'
export default class App extends React.Component {
state = {
inputValue: "",
todos: [
{
title: "물 3잔 마시기",
isComplete: false
},
{
title: "30분 이상 걷기",
isComplete: false
}
]
}
saveItem = () => {
//state를 문자열로 바꿔서 저장함
AsyncStorage.setItem('@todo:state',JSON.stringify(this.state))
}
....
먼저 react-native에서 AsyncStorage를 import 해줍니다.
그리고 saveItem
이라는 함수를 만들어줍니다.
AsyncStorage.setItem(‘@todo:state’,JSON.stringify(this.state))
AsyncStorage 모듈의 setItem 메소드는 AsyncStorage.setItem(key: string,value: string)
의 형식을 따릅니다. 그리고 key는 보통 @앱이름: 키 이름
으로 작성하는 것이 일반적입니다.
JSON.stringify()는 괄호안에 있는 내용을 JSON형태의 문자열로 변경해주는 열할을 합니다.
이제 state가 변경 될때마다 saveItem
을 호출하면 자체 저장소에 데이터가 저장될 것입니다.
만든 함수 호출하기
우리는 할 일의 완료 여부를 변경할 때, 할 일을 추가 할 때, 할 일을 삭제할 때 처럼 state가 변경되면 데이터를 저장해야합니다.
우리는 이러한 작업을 위해 this.setState 작업이 끝나면 saveItem
함수를 사용할 예정입니다. setState
메서드의 두번째 인자에 callback함수를 작성하면 됩니다.
//App.js
_makeTodoItem = ({ item, index }) => {
return (
<TodoItem
text={item.title}
isComplete={item.isComplete}
changeComplete={() => {
const newTodo = [...this.state.todos];
newTodo[index].isComplete = !newTodo[index].isComplete;
this.setState({todos:newTodo},this.saveItem);
}}
deleteItem={() => {
const newTodo = [...this.state.todos];
newTodo.splice(index,1);
this.setState({todos:newTodo},this.saveItem)
}} />
)
}
_changeText = (value) => {
this.setState({inputValue:value})
}
_addTodoItem = () => {
if(this.state.inputValue !== ''){
const Input = this.state.inputValue;
const prevItem = this.state.todos;
const newItem = { title: Input, isComplete: false}
this.setState({
inputValue: '',
todos: prevItem.concat(newItem)
},this.saveItem)
}
}
첫째로, 완료여부가 변경될 때
둘때로, 할 일을 삭제한 뒤
셋째로, 할 일을 추가한 뒤
각각의 setState의 callback함수로 saveItem
함수를 넣어줍니다. state설정이 끝난 뒤 saveItem
함수가 실행 됩니다.
앱이 로딩될 시 데이터 가져오기
현재 데이터가 변결될 때, 자체 저장소에 데이터를 저장하고 있습니다.
이제는 앱이 로딩될 때 저장된 데이터를 가져와서 보여주는 기능을 추가해봅시다.
// App.js
export default class App extends React.Component {
state = {
inputValue: "",
todos: [
{
title: "물 3잔 마시기",
isComplete: false
},
{
title: "30분 이상 걷기",
isComplete: false
}
]
}
componentWillMount() {
AsyncStorage.getItem('@todo:state').then((state)=> {
if( state != null){
this.setState(JSON.parse(state));
}
});
}
saveItem = () => {
//state를 문자열로 바꿔서 저장함
AsyncStorage.setItem('@todo:state',JSON.stringify(this.state));
}
....
componentWillMount
라는 함수를 추가해줍니다.
이 함수는 React의 라이프사이클 함수중 하나입니다. 라이프 사이클함수는 컴포넌트가 생성되기 전 후 및 데이터가 변경되어, 상태를 업데이트하기 전 후로 실행되는 함수입니다.
즉, 자동으로 React에서 생성해주는 함수이고, 그 중 componentWillMount는 컴포넌트가 모두 생성 된 후에 바로 실행됩니다. 이 함수안에서 데이터를 불러올 예정입니다.
AsyncStorage.getItem(key)
메소드를 써서 데이터를 가져옵니다. 가져온 후 데이터를 앱에 반영해줘야 하는데 .then
키워드를 사용해 promise
를 구현해 보겠습니다.
promise
는 위에서 사용한 callback함수와 비슷한 개념입니다. JSON.parse() 메서드는 아까 그 JSON 문자열의 구문을 분석해서 JavaScript 값이나 객체를 생성합니다.
이제 결과를 확인해 보겠습니다.