마이페이지, 비밀번호 재설정 등 유저 정보를 저장해놓고 어디서든 꺼내서 사용하기 위해 Recoil을 사용하였다. 하위 컴포넌트로 props를 이용해서 계속 넘겨주기 힘들고 관리하기 어려우니 전역변수처럼 사용하려는건데
바로바로 필요할 때 꺼내서 사용하니 정말 편리하다:)
1.RecoilRoot
Recoil을 사용하려면 RecoilRoot로 최상위 컴포넌트를 감싸줘야한다.
import React from 'react';
import { RecoilRoot } from 'recoil';
import { LogBox, Platform, StatusBar } from 'react-native';
import { SafeAreaProvider } from 'react-native-safe-area-context';
import Navigator from './screens/Navigator';
const App = () => {
LogBox.ignoreAllLogs();
return (
<SafeAreaProvider>
<RecoilRoot>
<StatusBar barStyle={Platform.OS === 'ios' ? 'dark-content' : 'light-content'} />
<Navigator />
</RecoilRoot>
</SafeAreaProvider>
);
};
export default App;
Atom : 컴포넌트끼리 공유가 가능한 가장 작은 단위 state
Atom은 상태의 단위이다.
Atom은 어떤 컴포넌트에서나 읽고 쓸 수 있으며, 값을 읽는 컴포넌트들은 암묵적으로 atom을 구독한다.
그래서 atom에 어떤 변화가 생기면 구독하는 모든 컴포넌트들이 재랜더링 된다.
유저의 상태를 관리하기 위해 user의 정보와 token을 저장했다
key와 default 값은 필수!!!
export const UserState = atom<UserModel.IUserModel | null>({
key: 'user',
default: null,
});
export const TokenState = atom<UserModel.ITokenModel | null>({
key: 'token',
default: null,
});
앱이 꺼져도 User의 정보를 유지하기 위해서 AsyncStorage를 사용하였다.
setItem으로 token과 user의 정보를 저장하였다.
(값을 저장할때는 반드시 문자열 타입이여야하고, 만약 객체나 배열타입을 저장하려면 JSON.stringify 함수를 사용해야한다)
나는 스플레쉬가 실행되면서 로딩하는 동안 getItem을 이용하여 유저 정보를 뿌려주었다.
(해당코드는 없음)
export const useAuth = () => {
const [user, setUser] = useRecoilState<UserModel.IUserModel | null>(UserState);
const setToken = useSetRecoilState<UserModel.ITokenModel | null>(TokenState);
const auth = useMemo(
() => ({
authenticate: async (user: UserModel.IUserModel) => {
await AsyncStorage.setItem('user', JSON.stringify(user));
setUser(user);
},
login: async (model: UserModel.IUserTokenModel) => {
const tokenModel = {
accessToken: model.accessToken,
refreshToken: model.refreshToken,
} as UserModel.ITokenModel;
await AsyncStorage.setItem('token', JSON.stringify(tokenModel));
await AsyncStorage.setItem('user', JSON.stringify(model));
setToken(tokenModel)
setUser(model);
},
logout: async () => {
await AsyncStorage.clear();
setToken(null);
setUser(null);
},
}),
[],
);
return { auth, setUser };
}
const [user, setUser] = useRecoilState<UserModel.IUserModel | null>(UserState);
const user = useRecoilValue<UserModel.IUserModel | null>(UserState);
const setToken = useSetRecoilState<UserModel.ITokenModel | null>(TokenState);
useSetRecoilState와 같이 비동기 setter 함수를 리턴하며 컴포넌트를 구독하지 않는다
const resetUser = useResetRecoilState(UserState);
1.setItem
특정 값을 저장
const auth = async () => {
try {
await AsyncStorage.setItem('user', JSON.stringify(user)); // 객체 형태 저장
} catch (e) {
// 예외 처리
}
}
2.getItem
특정 값을 불러옴
const model = await AsyncStorage.getItem('user');
2.clear()
모든 값을 초기화함
const clearAll = asycn () => {
try {
await AsyncStorage.clear();
} catch (e) {
// 예외 처리
}
}
<참고>
https://recoiljs.org/docs/introduction/getting-started/