탭은 페이지보다는 더 부드럽게 전환되기를 사용자 입장에서 기대하는데, 위 영상을 보면 탭을 이동할 때마다 화면이 깜빡이는 것을 볼 수 있다. 이는 좋지 않은 사용자 경험을 제공한다고 생각하였다.
그래서, 이를 reacat-navigation/bottom-tabs의 BottomTobBar로 구현해보고자 한다.
<aside> 📚 Bottom Tab Navigator 다이브
react-navigation/bottom-tabs 라이브러리를 사용하여 구현 가능하다.
createBottomTabNavigator : Tab Navigator를 만드는데 사용한다.
const Tab = createBottomTabNavigator();
function MyTabs() {
return (
<Tab.Navigator>
<Tab.Screen name="Home" component={HomeScreen} />
<Tab.Screen name="Settings" component={SettingsScreen} />
</Tab.Navigator>
);
}
TabBar를 보여주는 페이지가 있고, 보여주지 않아야 할 페이지가 있다. TobBar를 보여줄 페이지는 위 영상처럼 4개의 페이지(각 탭의 메인)에서이다. 그리고 그 탭에서 이동한 페이지이거나, 로그인 이전에는 보여주지 말아야 한다.
그래서 이 둘을 구분하고자 기존에 TabBar가 없는 컴포넌트를 기존 명칭인 WebViewContainer그대로 사용하고, TabBar를 보여줄 컴포넌트를 TabBarNavigatior라고 하였다.
// TabBarNavigator.tsx
export const WEBVIEW_SCREENS = [
{name: 'Matching', url: SOURCE_URL + '/grouping'},
{name: 'Union', url: SOURCE_URL + '/meeting/participate'},
{name: 'Community', url: SOURCE_URL + '/community'},
{name: 'Profile', url: SOURCE_URL + '/profile'},
];
const TabBarNavigator = () => {
const Screens = useMemo(
() => WEBVIEW_SCREENS.map(BottomTabNavigator.createScreen),
[],
);
return <BottomTabNavigator>{Screens}</BottomTabNavigator>;
};
export default TabBarNavigator;
BottomTabNavigator.createScreen을 이용해서 각 스크린을 만든다. 그리고 이 만든 스크린을 BottomTabNavigator의 children으로 넘긴다.
// BottomTabNavigator.tsx
const BottomTab = createBottomTabNavigator();
const BottomTabNavigator = ({children}: PropsWithChildren) => {
const props = useMemo(
() => ({
tabBar: (props: BottomTabBarProps) => <TabBar {...props} />,
screenOptions: {
headerShown: false,
lazy: false,
},
}),
[],
);
return <BottomTab.Navigator {...props}>{children}</BottomTab.Navigator>;
};
BottomTabNavigator.createScreen = ({
name,
url,
}: {
name: string;
url: string;
}) => (
<BottomTab.Screen
name={name}
component={WebViewContainer}
initialParams={{url, edges: ['top']}}
/>
);
export default BottomTabNavigator;
createBottomTabNaviagtor를 이용하여 BottomTab을 만들고, 스크린으로는 TabBar가 없는 WebViewContainer를 넘긴다.
추후 React Native스토리지로 마이그레이션하게되면 ReactNative 스토리지에서 토큰을 체크하고 → 존재한다면 TobBar를 보여주고, 존재하지 않는다면 보여주지 않는 방식으로 해도 될 거 같다.
하지만 TabBar를 웹뷰에서 관리하는 현 시점에서는, TabBar가 필요한 시점에 웹뷰 → 앱으로 메시지 전송, 필요하지 않을 때도 전송하는 방식으로 구현을 하고자 한다.
‘TabBar가 필요해요’메시지를 RN에 전송한다 : 토큰 설정 이후
export default function useLogin() {
const { refresh, replace } = useAppRouter();
const login = async ({ accessToken, refreshToken, userId }: LoginProps) => {
setTokenAtCookie({ accessToken, refreshToken, userId });
await sendMessageToReactNative({ type: 'SIGN_IN', data: 'LOGIN_SUCCESS' });
refresh();
replace('/grouping');
};
return { login };
}