i use stacknavigator & tabnavigator and i nested tab and stack
import {createNativeStackNavigator} from '@react-navigation/native-stack';
import {createBottomTabNavigator} from '@react-navigation/bottom-tabs';
const StackNav = () => {
const loginState = useSelector((state: RootState) => {
if (state.user.user) {
if (state.user.user?.ban) {
return 'Ban';
}
return 'LogIn';
} else {
return 'LogOut';
}
});
if (loginState === 'Ban') {
return (
<Stack.Navigator initialRouteName="Ban">
<Stack.Screen name="WebView" component={WebView} />
<Stack.Group screenOptions={{headerShown: false}}>
<Stack.Screen name="Ban" component={Ban} />
</Stack.Group>
</Stack.Navigator>
);
} else if (loginState === 'LogIn') {
return (
<Stack.Navigator initialRouteName="TabNav">
<Stack.Screen name="WebView" component={WebView} />
<Stack.Group screenOptions={{headerShown: false}}>
<Stack.Screen name="TabNav" component={TabNav} />
</Stack.Group>
</Stack.Navigator>
);
} else if (loginState === 'LogOut') {
return (
<Stack.Navigator initialRouteName="VideoScreen">
<Stack.Screen name="WebView" component={WebView} />
{/* login step*/}
<Stack.Group screenOptions={{headerShown: false}}>
<Stack.Screen name="VideoScreen" component={VideoScreen} />
<Stack.Screen
name="AuthenticationPhoneNumber"
component={AuthenticationPhoneNumber}
/>
<Stack.Screen name="VerificationCode" component={VerificationCode} />
</Stack.Group>
{/* sign up step */}
<Stack.Group screenOptions={{headerShown: false}}>
<Stack.Screen
name="TermsOfService"
component={TermsOfService}
options={{gestureEnabled: false}}
/>
<Stack.Screen name="Nickname" component={Nickname} />
<Stack.Screen name="BirthDate" component={BirthDate} />
<Stack.Screen name="Gender" component={Gender} />
<Stack.Screen name="ProfileImage" component={ProfileImage} />
<Stack.Screen name="Interest" component={Interest} />
<Stack.Screen name="Region" component={Region} />
<Stack.Screen
name="Complete"
component={Complete}
options={{gestureEnabled: false}}
/>
<Stack.Screen name="Withdraw" component={Withdraw} />
</Stack.Group>
</Stack.Navigator>
);
}
};
const TabNav = () => {
return (
<Tab.Navigator
backBehavior="none"
initialRouteName="HomeTab"
screenOptions={{headerShown: false, tabBarStyle: styles.tabBar}}>
<Tab.Screen
name="HomeTab"
component={HomeTab}
options={{
title: '홈',
tabBarLabelStyle: {
fontFamily: font.preReg,
fontSize: 12,
lineHeight: 12,
letterSpacing: -0.5,
},
tabBarIconStyle: {
width: 24,
height: 24,
flex: 0,
marginBottom: 4,
},
tabBarItemStyle: {
justifyContent: 'center',
},
tabBarInactiveTintColor: 'rgba(130, 136, 148, 1)',
tabBarActiveTintColor: 'rgba(49, 53, 61, 1)',
tabBarIcon: ({focused}) => {
const translateY = new Animated.Value(0);
if (focused) {
Animated.sequence([
Animated.timing(translateY, {
toValue: -10, // 위로 튀는 애니메이션
duration: 100, // 애니메이션 지속 시간 (ms)
useNativeDriver: false, // 네이티브 드라이버 사용 여부
}),
Animated.timing(translateY, {
toValue: 0, // 다시 아래로 튀는 애니메이션
duration: 100, // 애니메이션 지속 시간 (ms)
useNativeDriver: false, // 네이티브 드라이버 사용 여부
}),
]).start();
}
return (
<View>
<Animated.View style={{transform: [{translateY}]}}>
<Image
style={styles.tabIcon}
source={
focused
? require('../assets/images/ic_home_in.png')
: require('../assets/images/ic_home_out.png')
}
/>
</Animated.View>
</View>
);
},
}}
/>
<Tab.Screen
name="GatheringTab"
component={GatheringTab}
options={{
title: '모임찾기',
tabBarLabelStyle: {
fontFamily: font.preReg,
fontSize: 12,
lineHeight: 12,
letterSpacing: -0.5,
},
tabBarIconStyle: {
width: 24,
height: 24,
flex: 0,
marginBottom: 4,
},
tabBarItemStyle: {
justifyContent: 'center',
},
tabBarInactiveTintColor: 'rgba(130, 136, 148, 1)',
tabBarActiveTintColor: 'rgba(49, 53, 61, 1)',
tabBarIcon: ({focused}) => {
const translateY = new Animated.Value(0);
if (focused) {
Animated.sequence([
Animated.timing(translateY, {
toValue: -10, // 위로 튀는 애니메이션
duration: 100, // 애니메이션 지속 시간 (ms)
useNativeDriver: false, // 네이티브 드라이버 사용 여부
}),
Animated.timing(translateY, {
toValue: 0, // 다시 아래로 튀는 애니메이션
duration: 100, // 애니메이션 지속 시간 (ms)
useNativeDriver: false, // 네이티브 드라이버 사용 여부
}),
]).start();
}
return (
<View
style={
{
// borderWidth: 1,
}
}>
<Animated.View style={{transform: [{translateY}]}}>
<Image
style={styles.tabIcon}
source={
focused
? require('../assets/images/ic_search_in.png')
: require('../assets/images/ic_search_out.png')
}
/>
</Animated.View>
</View>
);
},
}}
/>
<Tab.Screen
name="FeedTab"
component={FeedTab}
options={{
title: '피드',
tabBarLabelStyle: {
fontFamily: font.preReg,
fontSize: 12,
lineHeight: 12,
letterSpacing: -0.5,
},
tabBarIconStyle: {
width: 24,
height: 24,
flex: 0,
marginBottom: 4,
},
tabBarItemStyle: {
justifyContent: 'center',
},
tabBarInactiveTintColor: 'rgba(130, 136, 148, 1)',
tabBarActiveTintColor: 'rgba(49, 53, 61, 1)',
tabBarIcon: ({focused}) => {
const translateY = new Animated.Value(0);
if (focused) {
Animated.sequence([
Animated.timing(translateY, {
toValue: -10, // 위로 튀는 애니메이션
duration: 100, // 애니메이션 지속 시간 (ms)
useNativeDriver: false, // 네이티브 드라이버 사용 여부
}),
Animated.timing(translateY, {
toValue: 0, // 다시 아래로 튀는 애니메이션
duration: 100, // 애니메이션 지속 시간 (ms)
useNativeDriver: false, // 네이티브 드라이버 사용 여부
}),
]).start();
}
return (
<View>
<Animated.View style={{transform: [{translateY}]}}>
<Image
style={styles.tabIcon}
source={
focused
? require('../assets/images/ic_feed_in.png')
: require('../assets/images/ic_feed_out.png')
}
/>
</Animated.View>
</View>
);
},
}}
/>
<Tab.Screen
name="MoreTab"
component={MoreTab}
options={{
title: '더보기',
tabBarLabelStyle: {
fontFamily: font.preReg,
fontSize: 12,
lineHeight: 12,
letterSpacing: -0.5,
},
tabBarIconStyle: {
width: 24,
height: 24,
flex: 0,
marginBottom: 4,
},
tabBarItemStyle: {
justifyContent: 'center',
},
tabBarInactiveTintColor: 'rgba(130, 136, 148, 1)',
tabBarActiveTintColor: 'rgba(49, 53, 61, 1)',
tabBarIcon: ({focused}) => {
const translateY = new Animated.Value(0);
if (focused) {
Animated.sequence([
Animated.timing(translateY, {
toValue: -10, // 위로 튀는 애니메이션
duration: 100, // 애니메이션 지속 시간 (ms)
useNativeDriver: false, // 네이티브 드라이버 사용 여부
}),
Animated.timing(translateY, {
toValue: 0, // 다시 아래로 튀는 애니메이션
duration: 100, // 애니메이션 지속 시간 (ms)
useNativeDriver: false, // 네이티브 드라이버 사용 여부
}),
]).start();
}
return (
<View>
<Animated.View style={{transform: [{translateY}]}}>
<Image
style={styles.tabIcon}
source={
focused
? require('../assets/images/ic_more_in.png')
: require('../assets/images/ic_more_out.png')
}
/>
</Animated.View>
</View>
);
},
}}
/>
</Tab.Navigator>
);
};
but in this case sometimes initialRouteName does not work correctly
when user state === Login , i expect routing to TavNav(HomeTab) but it go To webView
but if i chage the order right this
return (
<Stack.Navigator initialRouteName="TabNav">
<Stack.Group screenOptions={{headerShown: false}}>
<Stack.Screen name="TabNav" component={TabNav} />
</Stack.Group>
<Stack.Screen name="WebView" component={WebView} />
</Stack.Navigator>
it works correctly to Tabnav(HomeTab)
how can i solve this problem?
initialRoute works correctly in nested stack & tab navigator