학습내용
- 명령어로 프로젝트-expo 연결
- react-navigation
- useEffect vs useFocusEffect
- 다크/라이트 모드
eas update:configure
미로그인 상태라면 2번 전에 ID/비밀번호 우선 입력
라우팅 기능과 네비게이션 레이아웃을 제공하는 리액트 네이티브의 라이브러리
- 기본 설치
yarn add @react-navigation/native
- + expo로 관리시
npx expo install react-native-screens react-native-safe-area-context
- + CLI 사용시
npx expo install react-native-screens react-native-safe-area-context
📌 공식문서
프로젝트에 사용된 페이지들(
Stack.Screen
)을Stack.Navigator
에 등록시켜 페이지간 이동을 시켜주는 기능
import { createNativeStackNavigator } from "@react-navigation/native-stack";
const Stack = createNativeStackNavigator();
const Stacks = () => {
const Two = ({ navigation: { navigate } }) => {
return (
<TouchableOpacity onPress={() => navigate("three")}>
<Text>Two</Text>
</TouchableOpacity>
);
};
const Three = ({ navigation: { goBack } }) => {
return (
<TouchableOpacity onPress={() => goBack()}>
<Text>Three</Text>
</TouchableOpacity>
);
};
return (
<Stack.Navigator initialRouteName="mypage">
<Stack.Screen name="One" component={One} />
<Stack.Screen name="Two" component={Two} />
<Stack.Screen name="Three" component={Three} />
</Stack.Navigator>
);
};
- | Stack | Native Stack |
---|---|---|
특징 | 자바스크립트로 구현 | iOS와 안드로이드의 네이티브 모듈 참고 |
퍼포먼스 | - | 우세 |
기능 | - | iOS 큰 제목 기능 제공 |
사용자 정의 | 우세 | - |
Navigation prop을 참고하면 기본적인 기능 이외에도 별도의 옵션을 추가할 수 있다.
스크린 하단에 위치하는 네비게이터
import { createBottomTabNavigator } from "@react-navigation/bottom-tabs";
const Tab = createBottomTabNavigator();
const Tabs = () => {
return (
<Tab.Navigator>
<Tab.Screen name="Movies" component={Movies} />
<Tab.Screen name="MyPage" component={MyPage} />
</Tab.Navigator>
);
};
stack과 마찬가지로 prop을 활용해서 별도의 옵션을 추가할 수 있다.
이 밖에도 Drawer, Material Bottom Tabs, Material Top Tabs등의 네비게이터를 제공한다.
const MyPage = ({ navigation: { navigate } }) => {
useEffect(() => {
console.log("Mount"); // 최초 렌더링 시
return () => {
console.log("Unmount"); // 언마운트 시
};
}, []);
useFocusEffect(
useCallback(() => {
console.log("Focus"); // 컴포넌트가 현재 화면에 있을 시
return () => {
console.log("Blur"); // 컴포넌트가 현재 화면에서 벗어날 시
};
}, [])
);
return (
<View>
<SectionTitle>Movies</SectionTitle>
<TouchableOpacity
onPress={() =>
navigate("Stacks", { screen: "one", params: { id: 123 } })
}
>
<Text>Go To One Screen</Text>
</TouchableOpacity>
</View>
);
};
MyPage가 렌더링 될 때에는 "Mount"
와 "Focus"
를 모두 반환하지만 One으로 이동 시에는"Blur"
만 반환한다.
하위 컴포넌트에서 reset
메서드를 사용하면 상위 컴포넌트의 렌더링 히스토리를 초기화 한다.
export default function My({ navigation: { reset, navigate } }) {
return (
<View>
<Text>My</Text>
<TouchableOpacity
onPress={() =>
reset({
index: 0,
routes: [
{
name: "Stacks",
params: {
screen: "two",
},
},
],
})
}
>
<Text>Try unmounting</Text>
</TouchableOpacity>
</View>
);
}
- | useEffect | useFocusEffect |
---|---|---|
제공 | React Hook | React Native Hook |
감지 시기 | Mount, Unmount, dependency값 변경 | Focus, Blur |
화면 이탈시 | 렌더링 결과 보유 | Blur 처리 |
userInterFaceStyle
속성을 automatic
으로 변경. 속성을 변경하지 않으면 다크모드를 컨트롤 해도 기본값으로 적용된 light
모드만 반환한다.테마 제작
color.js
export const DARK_BG = "#57606f";
export const DARK_HEADER = "#2f3542";
export const DARK_POINT = "#eccc68";
export const LIGHT_BG = "#ffffff";
export const LIGHT_HEADER = "#f1f2f6";
export const LIGHT_POINT = "#5352ed";
export const darkTheme = {
point: DARK_POINT,
normal: "#ffffff",
};
export const lightTheme = {
point: LIGHT_POINT,![](https://velog.velcdn.com/images/cinephile/post/529516f0-a39d-4294-b82b-91c5204b0012/image.png)
normal: "#000000",
};
각각의 모드에 맞는 색상을 모아놓은 파일을 별도로 작성하면 훨씬 간결하고 가독성 좋은 코드를 작성할 수 있다.
iOS 시뮬레이터에서
cmd
+shfit
+a
를 누르면 다크/라이트 모드로 전환된다.
import {
DarkTheme,
DefaultTheme,
NavigationContainer,
} from "@react-navigation/native";
import useColorScheme from "react-native/Libraries/Utilities/useColorScheme";
import { ThemeProvider } from "@emotion/react";
import { darkTheme, lightTheme } from "./colors";
export default function App() {
const isDark = useColorScheme() === "dark";
return (
<ThemeProvider theme={isDark ? darkTheme : lightTheme}>
<NavigationContainer theme={isDark ? DarkTheme : DefaultTheme}>
<Root />
</NavigationContainer>
</ThemeProvider>
);
}
ThemeProvider
와 Navigator
에 별도의 테마 적용시 설정할 필요 XThemeProvider
const Subject = styled.Text`
color: ${(props) => props.theme.point};
`;
const Movies = ({ navigation: { navigate } }) => {
return (
<Subject>Top Rated Movies</Subject>
)
상위 컴포넌트에서 ThemeProvider
로 하위 컴포넌트를 감싸면 하위 컴포넌트에서 props.theme
으로 colors.js에 접근이 가능하다.
Navigator
const Tabs = () => {
const isDark = useColorScheme() === "dark";
return (
<Tab.Navigator
sceneContainerStyle={{
backgroundColor: isDark ? DARK_BG : LIGHT_BG,
}}
screenOptions={{
tabBarStyle: {
backgroundColor: isDark ? DARK_HEADER : LIGHT_HEADER,
},
tabBarActiveTintColor: isDark ? DARK_POINT : LIGHT_POINT,
headerStyle: { backgroundColor: isDark ? DARK_HEADER : LIGHT_HEADER },
headerTintColor: isDark ? DARK_POINT : LIGHT_POINT,
}}
>
)
각각의 네비게이터의 테마 설정