react와 react-native에서는 보통 react-navigation을 사용해서 페이지를 이동한다.
페이지를 이동을 위해서는 <NavigationContainer>로 앱 전체를 감싸고, navigation을 props로 넘겨주며 사용한다.
# 문제
현재 진행중인 프로젝트에서 axios intercepter에서 모든 api에 대한 예외 처리를 해줄 일이 생겼다.
모든 api에서 특정 에러가 발생하면 바로 로그인 페이지로 이동을 시켜야 하는데, axios intercepter에서는 navigaion props를 넘겨줄 수 없었다.
이럴 때는 useNavigation 이라는 hook을 이용하면 된다. useNavigation은 screen안에서 navigation props를 return하기 때문에 변수로 받아서 사용할 수 있다. (useNavigation에 대한 자세한 내용은 아래 참고에서 찾을 수 있다.)
하지만 여기서 또 한가지 문제가 있다. useNavigation은 hook이기 때문에 axios intercepter 안에서 사용할 수가 없다...
그렇다면 axios intercepter에서 hook을 사용할 수 있도록 컴포넌트로 만들면 된다!
# 해결
Interceptor라는 컴포넌트를 만들어서 axios intercepter가 작동하도록 만들었다. 그리고 해당 컴포넌트를 App.js에 넣어서 interceptor가 동작해야 하는 컴포넌트들을 감싸주었다.
이렇게 한 후 실행해봤더니 axios에서 에러가 나면 자동으로 로그인 화면으로 이동한다!
import {storage} from '@/config/storage';
import AsyncStorage from '@react-native-async-storage/async-storage';
import {useNavigation} from '@react-navigation/native';
import customAxios, {refreshAxios} from './axios';
export const Interceptor = ({children}) => {
const navigation = useNavigation(); // hook 사용
customAxios.interceptors.response.use(
res => res,
async err => {
...
if (
// 잘못된 토큰인 경우
) {
alert('잘못 된 토큰입니다! 로그인 화면으로 이동합니다.');
navigation.navigate('SignIn');
}
...
return Promise.reject(err);
},
);
return children;
};
import * as React from 'react';
import ReactNativeRecoilPersist, {
ReactNativeRecoilPersistGate,
} from 'react-native-recoil-persist';
import {NavigationContainer} from '@react-navigation/native';
import {StackNavigator} from './src/navigators/StackNavigator';
import {Interceptor} from '@/api/interceptor';
...
export default function App() {
const queryClient = new QueryClient();
return (
<QueryClientProvider client={queryClient}>
<RecoilRoot>
...
<NavigationContainer>
<Interceptor>
<StackNavigator />
</Interceptor>
</NavigationContainer>
...
</RecoilRoot>
</QueryClientProvider>
);
}
# 참고
useNavigation | React Navigation
reactjs - React router v6 how to use `navigate`. Axios interceptors - Stack Overflow
React hooks in Axios interceptors - DEV Community 👩💻👨💻
'트러블 슈팅 > react-native' 카테고리의 다른 글
[react-native] 빌드 오류 - Task :app:createBundleReleaseJsAndAssets FAILED (0) | 2023.05.24 |
---|---|
[react-native] Module AppRegisty is not a registered callable module... (feat. 어이없는 실수) (0) | 2023.03.12 |
[react-native] 실제 기기 연결 - adb devices 기기 목록에 안뜨는 현상 해결 (1) | 2023.03.12 |
[react-native] Metro (the local dev server) is run from the wrong folder error (0) | 2022.11.14 |
npm ELIFECYCLE 에러 (0) | 2022.11.14 |