[react-native] Context와 AsyncStorage (todo list app)

김래영·2020년 8월 27일
1

React-Native

목록 보기
2/10

todo-list-app (github)

props, state 이외에 전역에서 데이터를 관리하는 Context API와 앱을 종료하고 다시 실행해도 데이터가 유지되도록 AsyncStorage를 사용하여 투두리스트 앱을 만들어보았다. AsyncStorage는 로그인 할 때, 서버로부터 전달받은 토큰을 저장하거나 정보를 캐싱하는데 등 많은 곳에서 활용된다.

install

npm i @react-native-community/async-storage --save

cd ios

pod-install

cd ..

react-native link @react-native-community/async-storage

Context

  • creacteContext 함수에 초기 값을 할당하여 Context를 생성할 수 있다.
import React, { createContext, useState, useEffect } from 'react';

const TodoListContext = createContext({});
  • 공통 부모 컴포넌트에서 프로바이더를 사용하기 위해서 Context의 Provider 컴포넌트를 만든다.

AsyncStorage

  • AsyncStoragesetItem을 사용하여 데이터를 저장하고 getItem 을 사용하여 데이터를 가져올 수 있다.
  • setItems 을 사용할 때 키 값 형태로 데이터를 관리하기 때문에 JSON.stringfy 함수를 사용해서 문자열로 변환해서 저장한다.
  • ./src/context/TodoListContextProvider
    import React, { createContext, useState, useEffect } from 'react';
    import AsyncStorage from '@react-native-community/async-storage';

    const TodoListContext = createContext({});

    const TodoListContextProvider = ({ children }) => {
      const [todoList, setTodoList] = useState([]);

      const addTodoList = (todo) => {
        const list = [...todoList, todo];
        setTodoList(list);
        AsyncStorage.setItem('todoList', JSON.stringify(list)); 
      }

      const removeTodoList = (todoIndex) => {
        let list = [...todoList];
        list.splice(todoIndex, 1);
        setTodoList(list);
        AsyncStorage.setItem('todoList', JSON.stringify(list));
      };

      const initData = async () => {
        try {
          const list = await AsyncStorage.getItem('todoList');
          if (list !== null) {
            setTodoList(JSON.parse(list));
          }
        } catch (err) {
          console.log(err)
        }
      };

      useEffect(() => {
        initData();
      }, []);

      return (
        <TodoListContext.Provider  
          value={{    // provider value에 넣어준다.
            todoList,
            addTodoList,
            removeTodoList
          }}
        >
          {children} // 자식컴포넌트를 children 매개변수를 통해 전달받는다.
        </TodoListContext.Provider>
      );
    };

    export {
      TodoListContext,
      TodoListContextProvider
    };
  • 앞에서 만든 ContextProvider 컴포넌트를 불러와 상단 부모 컴포넌트로 감싸주면 하위의 모든 컴포넌트에서 Context를 사용할 수 있다.
    import React from 'react';

    import { TodoListContextProvider } from './context/TodoListContextProvider';
    import TodoListView from './screens/TodoListView';
    import { Provider as PaperProvider } from 'react-native-paper';

    const App = () => {
      return (
        <PaperProvider>
          <TodoListContextProvider>  // 상위에서 감싸준다.
            <TodoListView />
          </TodoListContextProvider>
        </PaperProvider>
      );
    };

    export default App;
  • 하위 컴포넌트에서 사용할 때 아래와 같이 import해서 value값을 사용할 수 있다.
    import { TodoListContext } from '../../context/TodoListContextProvider';

    export default () => {
      const { todoList, removeTodoList } = useContext(TodoListContext);

      return (
        <View 
          todoList={todoList}
          removeTodoList={removeTodoList}
        />
      );
    };

Usage

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

const storeData = async (value) => {
  try {
    await AsyncStorage.setItem('@storage_Key', value)
  } catch (e) {
    // saving error
  }
}
import AsyncStorage from '@react-native-community/async-storage';

const storeData = async (value) => {
  try {
    const jsonValue = JSON.stringify(value)
    await AsyncStorage.setItem('@storage_Key', jsonValue)
  } catch (e) {
    // saving error
  }
}
profile
개발 노트

0개의 댓글