컴포넌트 모달의 state를 가지고 있으면 state가 바뀔 때마다 같이 랜더링 된다.
또 별도의 스크린으로 되어 있으면 어디서든 쉽게 접근할 수 있다.
메인 navigation
<NavigationContainer theme={mode === "dark" ? MyDarkTheme : MyTheme}>
<Root.Navigator
screenOptions={() => ({
headerShown: false,
})}
**mode="modal"**
>
{!!!auth ? (
<Root.Screen name="NoAuthStacks" component={NoAuthStacks} />
) : (
<>
<Root.Screen name="BottomTabs" component={BottomTabs} />
<Root.Screen name="Stacks" component={Stacks} />
</>
)}
**<Root.Screen
name="ModalStacks"
component={ModalStacks}
options={{
gestureEnabled: false,
animationEnabled: false,
cardStyle: { backgroundColor: "transparent" },
cardOverlayEnabled: true,
}}
/>**
</Root.Navigator>
</NavigationContainer>
모달을 pop
해주기 위해서 최상단 navigator mode="modal"
로 해준다.
import React from "react";
import { createStackNavigator } from "@react-navigation/stack";
import { AlertScreen } from "@screens/ModalStacks";
const ModalStack = createStackNavigator();
const ModalStacks = () => {
return (
<ModalStack.Navigator
headerMode="none"
mode="modal"
screenOptions={{
**headerShown: false,
cardStyle: { backgroundColor: "#00000060" },
cardOverlayEnabled: true,
animationEnabled: false,
gestureEnabled: false,**
}}
>
<ModalStack.Screen name="AlertScreen" component={AlertScreen} />
</ModalStack.Navigator>
);
};
export default ModalStacks;
import { useNavigation, useRoute } from "@react-navigation/native";
import { ModaRouteProps } from "@types";
import React, { useEffect, useRef } from "react";
import { View, Button, Text, Animated, Easing } from "react-native";
const AlertScreen = () => {
const {
params: { title, content },
} = useRoute();
const nav = useNavigation();
const opacity = useRef(new Animated.Value(0)).current;
const translateY = opacity.interpolate({
inputRange: [0, 1],
outputRange: [500, 0],
});
useEffect(() => {
Animated.timing(opacity, {
toValue: 1,
duration: 150,
useNativeDriver: true,
easing: Easing.inOut(Easing.ease),
}).start();
}, []);
const onPress = () => {
Animated.timing(opacity, {
toValue: 0,
duration: 100,
useNativeDriver: true,
easing: Easing.inOut(Easing.ease),
}).start(nav.goBack);
};
return (
<View style={{ flex: 1, justifyContent: "center" }}>
<Animated.View
style={{
marginHorizontal: 30,
opacity,
transform: [{ translateY }],
}}
>
<Button
title="확인"
onPress={onPress}
weight="medium"
height={48}
/>
</Animated.View>
</View>
);
};
export default AlertScreen;