React Navigation 설치
npx expo install react-native-screens react-native-safe-area-context
npm으로 설치할 수도 있으나 npx로 설치해야, react-navigation 을 expo에 딱 맞는 버전으로 설치해준다.
npm으로는 3.3으로 설치됨 npx로 설치할 때는 4.3
NavigationContainer 로 감싸줘야한다.
import * as React from 'react';
import { NavigationContainer } from '@react-navigation/native';
export default function App() {
return (
<NavigationContainer>{/* Rest of your app code */}</NavigationContainer>
);
}
Stack Navigator 사용하기
종류가 두가지있음
- Stack (js로 만듬)
- Native Stack (native 에 맞게 제작)
안드로이드 ios 에 모두 맞게 만들어진 것은 Native Stack 네비게이터임
스크린을 쌓는 것이 stack의 원리 이다. 뒤로 돌아갈 때는 pop 되는 것임.
import SignInScreen from '../screens/SigninScreen';
const {
createNativeStackNavigator,
} = require('@react-navigation/native-stack');
const Stack = createNativeStackNavigator;
const AuthStack = () => {
return (
<Stack.Navigator>
<Stack.Screen
name={'SignIn'}
component={SignInScreen}
></Stack.Screen>
</Stack.Navigator>
);
};
export default AuthStack;
위와 같이 AuthStack.js 파일을 만들어서 네비게이션 설정 해준다.
그러면 App.js에서
const App = () => {
return (
<NavigationContainer>
<StatusBar style="dark" />
<AuthStack />
</NavigationContainer>
);
};
위와 같이 해주면 Navigation을 써서 화면 전환을 해줄 수 있다.
navigation, route
navigation 함수를 이용해서 route 전환을 해줄 수 있다.
const SignInScreen = ({ navigation, route }) => {
...
navigation.push('List');
위와 같이 기본 함수컴포넌트에 전달할 때, navigation, route 정보를 주고 받으며
navigation.push 함수를 사용하여 넣어준다.
- push : 화면을 쌓으면서 이동
- navigate : route로 이동하는 것임.
route.params 안에서 변수를 전달할 수 있다.
option 설정
방법은 3가지
- screenOptions
- options
- navigation.setOptions
우선순위는 setOptions가 가장 높음 덮어쓰기가 됨.
<Stack.Navigator
initialRouteName="List"
screenOptions=\{\{
contentStyle: {
backgroundColor: '#fff',
},
\}\}
>
위와 같이 해주면 모든 color가 흰색이 됨
<Stack.Navigator
initialRouteName="List"
screenOptions=\{\{
contentStyle: {
backgroundColor: '#fff',
},
\}\}
>
<Stack.Screen
name={'List'}
component={ListScreen}
options={{
contentStyle: {
backgroundColor: 'lavender',
borderRadius: 30,
},
}}
/>
<Stack.Screen name={'SignIn'} component={SignInScreen} />
</Stack.Navigator>
덮어써져서 option의 속성을 가져가는 것을 볼 수 있음.
useEffect(() => {
navigation.setOptions({
contentStyle: {
backgroundColor: 'lightgray',
},
});
});
위와 같이 해주면 회색으로 칠해짐.
헤더 타이틀 변경
<Stack.Screen
name={'SignIn'}
component={SignInScreen}
options={{
title: 'ToDo List',
}}
/>
위와 같이title을 설정해줄 수 있음.
title 중앙정렬
<Stack.Navigator
initialRouteName="List"
screenOptions={{
contentStyle: {
backgroundColor: WHITE,
},
headerTitleAlign: 'center',
}}
>
움직일때마다 바뀌게끔 만들어줌
headerTitle: (props) => {
return (
<Pressable>
<Text style={{ color: props.tintColor }}> {props.children}</Text>
</Pressable>
);
},
navigation 에서 설정하는 props를 가져가서 받을 수 있다.
헤더 왼쪽 버튼
headerLeft: ({ canGoBack, tintColor }) => {
const navigation = useNavigation();
if (!canGoBack) {
return null;
} else {
return (
<Pressable onPress={navigation.goBack}>
<MaterialCommunityIcons name="chevron-left" size={30} color={tintColor} />
</Pressable>
);
}
},
위와 같이 커스터마이징 할 수 있다.
여기서 유념해야하는 것은 navigation은 context가 다른 경우 useNavigation으로 가져올 수 있다는 점!
이를 함수로 만들어서 아래와 같이 정리하였음. HeaderLeftButton.js
import { Button, StyleSheet, View, Text } from 'react-native';
const ListScreen = ({ navigation, route }) => {
console.log(route.params);
return (
<View style={styles.container}>
<Text>ListScreen</Text>
<Button
title="navigate"
onPress={() => navigation.push('SignIn', { ts: Date.now() })}
></Button>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
});
export default ListScreen;
- hitslop 이라는 option을 주면 클릭의 오차범위를 확대할 수 있음.
<Pressable onPress={navigation.goBack} hitSlop={10}>
헤더의 오른쪽 버튼 추가
headerRight 에 옵션 주면 됨
- 안전한 영역에만 자식 컴포넌트가 렌더링 되도록 SafeAreaView 컴포넌트를 사용하면 된다.