
앱의 현재 상태가 Background인지, Foreground인지 체크를 한 뒤, 상황에 맞게 SecureStore에 담아 저장하고 꺼내사용하자.
import React, {useRef, useState, useEffect} from 'react';
import {AppState, StyleSheet, Text, View} from 'react-native';
const AppStateExample = () => {
const appState = useRef(AppState.currentState);
const [appStateVisible, setAppStateVisible] = useState(appState.current);
useEffect(() => {
const subscription = AppState.addEventListener('change', nextAppState => {
if (
appState.current.match(/inactive|background/) &&
nextAppState === 'active'
) {
console.log('App has come to the foreground!');
}
appState.current = nextAppState;
setAppStateVisible(appState.current);
console.log('AppState', appState.current);
});
return () => {
subscription.remove();
};
}, []);
return (
<View style={styles.container}>
<Text>Current state is: {appStateVisible}</Text>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
});
export default AppStateExample;
import React, { useRef, useEffect } from "react";
import { AppState } from "react-native";
import IndexStore from "../stores/IndexStore";
import * as SecureStore from "expo-secure-store";
const CurrentAppState = () => {
const appState = useRef(AppState.currentState);
const stores = IndexStore();
useEffect(() => {
secureStorageToStore();
const subscription = AppState.addEventListener("change", (nextAppState) => {
if (appState.current.match(/background/) && nextAppState === "active") {
secureStorageToStore();
} else if (appState.current.match(/active/) && nextAppState === "background") {
storeToSecureStorage();
}
appState.current = nextAppState;
});
return () => {
if (subscription) {
subscription.remove();
}
};
}, []);
const secureStorageToStore = async () => {
for (let key in stores) {
const storeData = await SecureStore.getItemAsync(key);
if (storeData) {
const parsedData = JSON.parse(storeData);
Object.assign(stores[key], parsedData);
}
}
};
const storeToSecureStorage = async () => {
for (let key in stores) {
await SecureStore.setItemAsync(key, JSON.stringify(stores[key]));
}
};
return null;
};
export default CurrentAppState;
초반부분은 똑같다. 현 상태가 background인지, foreground인지 체크해주고, 데이터들을 옮기는 함수를 호출한다. (inactive는 iOS다.)
stores의 key를 가져오고, 그 key를 기준으로 데이터를 Secure에 stringify해서 담는다.
반대의 경우도 똑같다. 저장된 데이터들을 파싱해서 stores[key]에 파싱된 데이터들을 덮어쓴다.
그러면 store의 수가 많아져도, 코드의 로직은 변함이 없다. 그렇게 작성했다.
CurrentAppState 컴포넌트를, 모든 페이지에서 적용되게 해야한다.
현재 우리 프로젝트의 최상위 파일은, App.tsx이다.
...
import CurrentAppState from "./src/components/CurrentAppState";
const App = () => {
const Stack = createNativeStackNavigator();
Sentry.init({
dsn: sentry_dsn,
tracesSampleRate: 1.0,
});
return (
<>
<CurrentAppState />
<NavigationContainer>
<Stack.Navigator initialRouteName="Main">
<Stack.Screen name="Main" component={Main} />
<Stack.Screen name="Album" component={Album} />
<Stack.Screen name="SideMenu" component={SideMenu} />
...
CurrentAppState 컴포넌트가 다 적용되게 위치시켜준다.
AppState코드는, 계속해서 바뀔 것 같다. 활용처가 많아보인다.
끗