네비게이션 시작하기 리액트 네비게이션 공식 문서(https://reactnavigation.org/)를 살펴보면 가장 첫 번째에 설치 가이드를 확인 할 수 있습니다
네비게이션 설치하기 공식 문서 사용법 그대로, 설치하라는 두 줄의 코드를 차례대로 설치 합니다. 설치할 땐, vscode의 view 탭을 눌러 terminal을 연 다음 진행하면 편합니다 🚩네비게이션 기본 라이브러리 설치 > yarn add @react-navigation/native
🚩 네비게이션 추가 라이브러리 설치 >expo install react-native-gesture-handler react-native-reanimated react-native-screens react-native-safe-area-context @react-native-community/masked-view
❓ yarn 없으시면 > npm install --global yarn 이걸로 깔고 위 코드 실행하세요~ ❗ yarn 버전 확인 > yarn --version
[프로젝트 골격 만들기] wegram 프로젝트에 스택 네비게이터 적용
컴포넌트들에 페이지 기능을 부여하기 stack - 쌓다,, 컴포넌트도 쌓아 나가는 과정으로 생각해쥬시떼
👉스텍 네비게이션 설치 > yarn add @react-navigation/stack ✅미리 만든 navigations 폴더에 StackNavigator.jsx 파일을 만들고 아래 코드를 넣어봅시다. pages 폴더에 Loading.jsx만 제외하고 모두 페이지화, 즉 스택 네비게이터 연결을 완료했습니다. 어디에 연결해줬는지에 집중해보자면, <Stack.Screen>에 연결시켜줬는데요!
즉, 크게 <Stack.Navigator>라는 목차 페이지에, 컴포넌트들을 연결시킨 <Stack.Screen> 들을 나열한 구조입니다.
이제 앱 전체에 대한 목차를 갖게 되었으니, 앱 상의 최상단 파일 즉, App.jsx에 목차를 알려줄 차례입니다.NavigationContainer가 모든 페이지를 감싸주는 상자 같은 느낌StackNavigator.jsx 상의 <Stack.Screen> 순서상 가장 위에 있는 페이지가 먼저 보이게 됩니다.App.jsx = 루트 파일 즉, 리엑트 네이티브 에서 가장 먼저 열리는 파일! 진입점이 되는 파일!
🚩진입점이 되는 파일에서 NavigationContainer 로 가장 먼저 감쌈으로써 모든 위그램 프로젝트에서 페이지들과 도구(기능)들을 언제든 사용할 수 있는 것👍
페이지 헤더 스타일 없애기 스택 네비게이터는 페이지화를 거친 컴포넌트에 기본적으로 헤더 스타일을 부여해줍니다. 다음과같은 헤더가 확인 되시죠?
우린 이번 주차에 직접 헤더를 구성할 예정이기 때문에, 이 헤더를 숨기도록 하게습니다. 스택 네비게이터 상의 헤더 옵션 코드를 화면의 코드로 변경해주세요
[프로젝트 골격 만들기] navigate 함수와 route.param
스택 네비게이터가 페이지들에게 주는 선물 Stack.Screen에 의해 페이지화가 된 pages 폴더의 컴포넌트들은 자동으로 갖게 되는 기능들이 있습니다.
함수 파라미터 부분에서도 비구조 할당을 활용하여 스택 네비게이터가 부여해주는 기능 중 원하는 기능만 바로 꺼내 사용할 수 있습니다.
//navigation 객체가 가지고 있는 두 함수(setOptions와 navigate)
export default function SignUpPage({ navigation, route }) {}
👉Stack.Screen은 헤더 부분의 제목과 스타일을 변경해주는 navigation.setOptions부터 페이지 이동, 데이터 전달, 데이터 받기 등 다양한 기능들을 제공해줍니다.
✔navigation과 route 를 어디서 어떻게 꺼내 사용하는지에 집중해서 해당 기능들을 이용하여 앱다운 앱 기능을 구현해보도록 하겠습니다.
페이지 이동 지금 처음 보이는 화면은 로그인 페이지입니다. 해당 페이지에서 회원가입 페이지로 이동하기 위해 다음과 같은 함수가 딸린 버튼을 두도록 하겠습니다. 일단 SignInPage.jsx 코드를 다음과 같이 변경해봅시다. (아주 조금 옷도 입혔습니다 😇) 회원가입 하러가기 버튼을 누르면 회원 가입 페이지로 이동하네요! 👉이동하고 나서 다시 뒤로 가려면 아이폰은 왼쪽에서 오른쪽으로 슬라이드 안드로이드는 뒤로가기 버튼을 이용하면 됩니다.
중요한 것은 이 부분입니다. ❗ SignInPage 컴포넌트에 navigation이 전달되고 있습니다. 스택 네비게이터가 넘겨주고 있는 값으로, 이 navigation에는 페이지를 이동시키는 navigate 함수가 들어 있습니다. 해당 함수에 이동하고자 하는 페이지 이름을 문자열로 넣어주면 goSignUp 함수가 실행될 때 navigate 함수도 실행되어서 페이지를 이동하게 됩니다.
탭 네비게이터 설치 & 적용 탭 네비게이터도 하나의 페이지라고 생각하시면 간단합니다. 큰 도화지에 여러 페이지가 들어 있고 하단에 어떤 페이지로 갈지 버튼을 둔 모습이죠. 따라서 탭 네비게이터를 실제 프로젝트에 적용할 땐, 어떤 페이지를 탭 네비게이터로 묶을 것인지 결정해야합니다. 우린 메인페이지, 글 추가 페이지, 마이페이지를 탭 네비게이터로 묶을 예정입니다.
navigations 폴더에 TabNabigator.jsx 파일을 만들어 다음 코드를 입력해주세요 탭 네비게이터 또한 페이지입니다. 페이지의 기능을 하려면 StackNavigator에 등록이 되어야 했습니다. StackNavigator에 TabNavigator.jsx를 다음과 같이 적용해주세요!
또한 탭 네비게이터로 묶인 MainPage, AddPage, MyPage는 StackNavigator에서 제거해주세요!탭 네비게이터를 StackNavigator 상의 Screen 순서에서 가장 위에 위치해 놨기 때문에, 방금 구현한 탭 네비게이터 페이지가 보입니다.
[탭 네비게이터 다루기] 탭 네비게이터 활용
하단 버튼 꾸미기 적용한 하단 탭 버튼은 위 이미지와 같이 각 페이지 이름이 노출되고 있고, 누른 화면은 페이지 이름이 하이라이트 되어 보여지고 있습니다. 보통은 인스타그램처럼 로고만 있는 것을 주로 볼 수 있습니다. 👉 하이라이트된 부분은 은근슬쩍 집어넣은 아래 코드로 간단히 해결했습니다. `activeTintColor`는 누른 버튼의 색을 결정하고 `inactiveTintColor`는 누르지 않은 나머지 버튼의 색을 결정합니다.
이제부턴 아이콘을 탭 버튼에 두어서 좀더 일반적인 앱처럼 꾸며보도록 하겠습니다.
리액트 네이티브는 기본적으로 아이콘들을 제공해줍니다. 따라서 필요한 아이콘은 상단에 임포트 한 후 바로 사용할 수 있습니다.
👉 <Tabs.Navigator> 에는 screenOption이란 속성이 존재합니다. 화면에 나타나는 부분을 이 속성을 통해 꾸밀 수 있는데요!
비슷하게 이미 우린 하단에 페이지 이름을 나타내는 tabBarOptions 부분을 배운 바 있습니다. screenOption 아이콘을 넣을 수 있게 친절히 제공해주는 도구도 있는데요! 그게 바로 tabBarIcon 부분입니다.
👉 위에서부터 살펴보자면
`screenOptions={({ route }) => ({ })` 에서 route 부분은 어떤 페이지를 현재 사용자가 보고 있는지에 대한 정보를 담고 있습니다.
그 내부의 `tabBarIcon: ({ focused }) => {}})` 부분은 특정 탭을 눌렀을 때, 즉 포커싱(focused) 되었을때 어떠한 아이콘을 보여줄지를 나타냅니다 (각각의 탭에 연결된 페이지들이 지금 포커싱=사용자가 보고있는지 아닌지 확인하는게 focused )
상단에서 임포트한 아이콘 다발(`import { Ionicons } from '@expo/vector-icons';)`은 기기들 마다 제공되는 아이콘이 다르기때문에 iOS인지 안드로이드인지 구별한 후 적절히 이름을 바꿔줘야 합니다. ✅ iOS는 일단적으로 `ios-` 가 붙고 안드로이드에는 `md-` 가 붙습니다.
따라서 (리액트에서 제공해주는 platform.OS 기능에 삼항연산자 구조로 붙여주면) 1) 어떤 페이지를 보고 있는지 페이지 이름이 들어 있는 route.name을 살펴보고 2) iOS인지 안드로이드인지 살펴보고 3) 그에 맞는 아이콘을 iconName 변수에 최종적으로 담는 겁니다.
아이콘 리스트는 공식 문서에 있지만 이렇게 가져와봤습니다 🙂 ionicons가 ios,android 다 제공해쥼 expo 아이콘 모음 : https://icons.expo.fyi/
해당 탭에 들어 왔을 때 특정 이벤트 실행하기
👉 특정 탭 버튼을 눌러 해당 페이지가 보일 때, 이벤트 팝업을 띄우거나 혹은 데이터를 새로 가지고 오려면 어떻게 해야할까요? 다음과 같이 말이죠!
useEffect에는 숨겨진 기능이 있는데, 그게 바로 return 구문입니다. 이 구문은 현재 화면이 바뀔 때 정리할 것들을 담아놓습니다. 즉, const unsubscrbie 에 팝업 기능을 담아 뒀었기 때문에, 팝업이 딱 한 번만 실행되려면, 정리할 것들 즉 unsubscrbie를 return 에 둬야합니다.
NativeBase 설치 NativeBase 도구함을 설치한 다음, Expo에서 제공해주는 다양한 폰트들과 아이콘이 들어있는 도구까지 설치합니다. ❗최근 native-base가 업데이트되어서, 구글 검색으로 찾아 들어가게되시는 사이트는 3.0 즉, 최신 버전입니다. 최신 버전은 최신 리엑트 네이티브와 충돌이 나고 있으므로, (ttps://docs-v2.nativebase.io/docs/GetStarted.html) 꼭 이 주소로 들어가 2.0 버전의 native-base를 살펴보시기 바랍니다.
✅NativeBase 도구 설치 > yarn add native-base@2 --save ✅Expo 폰트 도구 설치 > expo install expo-font
그림 그릴 때 옆에 색연필, 붓, 물감 등을 준비해놓고 그림을 그리듯 설치한 NativeBase와 Expo 폰트들을 앱이 시작할 때 준비시켜놓습니다
👉 `Roboto` 라는 것은 사실 "Roboto는 Google에서 모바일 운영 체제 Android의 시스템 글꼴로 개발 한 네오 그로테스크 한 산세 리프 서체 제품군으로 2011 년 Android 4.0 "Ice Cream Sandwich"용으로 출시되었습니다"* 글꼴 이름입니다. 즉, `Roboto`라는 폰트를 사용하기 위해 미리 준비한 것이구요! 나중에 앱 개발에 숙달되고, 다른 폰트들을 사용하고 싶다면, `Font.loadAsync({})` 부분에 설정하시면 됩니다. **혹시 Roboto is not system font 블라블라 라면서 경고 메시지가 나온다면! 해당 두 코드 두 줄을 없애주세요! 디바이스 기종별, OS 별로 해당 폰트가 지원되지 않을 수도 있습니다.
👉 일부러 폰트 준비할 시간을 줬습니다. `setTimeout`은 지연 자바스크립트 문법으로 1000은 1초입니다. 따라서 1초 뒤에 `ready` 상태를 풀게끔 해놨어요!
앱을 껐다가 켜보시면, 처음엔 `로딩 페이지` 가 보였다가, 1초 뒤 탭네비게이터의 첫 화면 `MainPage`가 보이게 됩니다.
무거운 이미지, 무거운 폰트파일, 데이터 등을 미리 준비할 땐 시간이 필요할 수도 있으니 이렇게 지연시간을 주기도 합니다.
`useEffect()` 안에서 상태 관리를 하게 되면, Expo에서 경고를 보냅니다. 규칙이 좀 많죠 😂 따라서 상태 관리를 useEffect 밖에서 하기 위한 함수를 만들어 외부에서 관리하게끔 코드를 구성했습니다.
`loadFont()`
또한, `loadFont()` 함수 내부에선 자바스크립트 문법이 `async / await`를 통해 폰트 로딩 → 준비 상태 변경 로직이 순서대로 진행됩니다.
✅반영된 App.jsx
[NativeBase&컴포넌트] NativeBase 기본
NativeBase 기본 사용방법
👉 되게 별 거 아닌 것 같지만, 특정 입력 태그를 눌렀을 때 화면이 키보드 위로 올라가게끔 해주는 기능을 NativeBase는 Content 태그라는 컴포넌트에 담아서 제공을 해줍니다.
또 한 가지, 가장 큰 화두 레이아웃! 은 어떤 식으로 제공하고 있을까요? 🤦♀️❗저는 아래 코드 적용 후 아래 그림의 에러가 났는데 지나가던 구원자 덕분에 해결 했습니다 어제 제가 yarn add native-base@2 --save 를 깔긴 했는데 다 깔린게 맞는지 체크를 안했나봐요^_ㅠ 다시 깔린거 확인하니 되더라구요! (윈도우 사용자들은 꼭 서버 끄고 깝시다!)
다시 공부로 돌아오면....!! 굉장히 직관적으로 제공해줍니다. 가로로 구분할지 세로로 구분할지에 대해 Col, Row 태그로 결정할 수 있고 size 속성값으로 영역의 범위를 결정할 수 있습니다. 👉 이 밖에도 다양하게 제공되는 태그들에는 여러 속성들이 존재합니다. 예컨대 `Intput` 이란 태그는 사용자들에게 정보를 제공받는 입력란 기능을 하는데요! 이 `Input` 태그에 `picker` 속성을 넣으면 선택할 수 있는 입력란이 되고, `last`를 입력하면 화면 가로 길이를 꽉채우는 스타일도 줍니다. 이렇게 스타일부터 기능까지 쉽게 구현할 수 있게 해주는 NativeBase 도구로 여러분과 함께 다섯 화면을 같이 만들 예정입니다. 어떤 식으로 접근하는지 차근차근 같이 보면서 앱 디자인을 정복해봅시다!
*NativeBase 는 밑그림을 제공해주고 우리는 색칠과 약간의 수정을 가미하는 것
[NativeBase&컴포넌트] 로그인 페이지 만들기
만들화면 1. Container로 전체 영역을 잡고 ImageBackground로 이미지를 넣음
2. Content태그 안에서도 flex를 써서 영역을 주었고, contentContainerStyle로 (얘는 스크롤 View태그에서 썼던 속성값) Content태그는 스크롤 View 기능까지 가지고 있기 때문에 Content에 Flex 기능을 적용하고 싶으면 contentContainerStyle속성으로 옷을 입혀줘야함!!@@ scrollEnabled={false} <- 로그인 하면서 스크롤 기능을 빼겠다라고 해서 false로 두었음 3. 사용자들이 입력 받는 그런 영역을 만들 때는 Form태그로 영역을 지정, 이메일/비번 등의 하나의 항목은 Item 태그로 영역을 나누고, 어떤 이름인지 내용을 받는지 내용을 쓸때는 label태그, 사용자들한테 값을 받을때는 input태그를 써줌
함께 만들기 ✅유의해서 볼 코드
1) <ImageBackground></ImageBackground> : 앱 전체 배경 화면을 결정 2) Content 태그에서도 flex 사용하여 전체 레이아웃 차지 가능, 정렬도 가능 3) React Native와 태그 비교
만들화면 1) input.jsx signinpage의 title을 넘겨받고있음! 넘겨받은 title을 label에 적용함 (이메일 넘겨받으면 어떤 사람들이 들어가냐 에 따라 나오는 결과값이 달라지는 것.. 똑같은 item input태그라도 넘겨받은 값이 다르니 이메일/비밀번호 쓰게 되는 것)2) signInPage.jsx 3) SignUpPage.jsx
함께 만들기 ✅유의해서 볼 코드 1) Item 태그 영역의 컴포넌트화: Item 부분에 중복된 코드가 너무 많으니 컴포넌트로 떼어내서 코드 재사용을 꾀했습니다! 2) navigation.navigate 함수가 아닌 goBack() 함수를 이용해 뒤로가기, 즉 로그인 페이지로 돌아가는 방법 (회원가입 페이지도 스택 네이게이터로 페이지 화 된 페이지임!)
**(ImageBackgroud태그는 다른 스타일과 다른 태그들의 영향을 받지않음 ㅇㅁㅇ,리액트 네이티브에 기본 내장된 태그로 그 위에 쌓이는 어떠한 태그와 속성들에 상관 없이 배경화면이 갖춰짐)
[NativeBase&컴포넌트] 메인 페이지 만들기: 헤더,카드
만들화면
함께 만들기 👉MainPage.jsx를 바로 확인하면서 코드를 진행하기 위해, StackNavigator.jsx의 스크린 순서를 다음과 같이 변경해주세요 stcak.screen상 가장 위에 있어야 앱 키자마자 메인화면이 보임✅이미지 로딩 자연스럽게 처리해주는 react-native-image-blur-loading 설치하기 (yarn add react-native-image-blur-loading) 팝업 뜨는 것도 이제 불필요하니 해당 코드를 없애주세요! ✅유의해서 볼 코드 1) Header의 배경색을 없애는 속성: <Header transparent> transparent로 기본적으로 갖고있는 보더라인 사라지게함! 2) 이미지를 지연 없이 자연스럽게 부르기 위한 react-native-image-blur-loading 이 쓰였다는 점 withIndicator<- 로딩 되는 뱅뱅 도는? 그런걸 보여준다고 함...ㅎㅎ, thumbnailSource={image}<- 이미지가 로딩 되기 전 회사의 로고처럼 작은 용량을 먼저 보이게 해줌, Grid를 통해 영역을 나눠줌 공식문서에서 제공해주는 card와 carditem
[NativeBase&컴포넌트] 메인 페이지 만들기: 완성
만들화면
함께 만들기 mainpage/Grid로 배너 영역 설정/return-cardcomponent를 이용한 반복문(디테일 페이지로 이동시키는 네비게이트 사용) ✅유의해서 볼 코드 1) padding과 마진은 inline 스타일로 적절히 이격을 표현했다는 점! 2) data.json을 불러와 카드 컴포넌트로 데이터를 넘겨서 데이터를 표현했다는 점!
👀 👉 공식 문서에 가보면 이 밖에 아주 다양한 애니메이션들을 소개하고 있습니다. 컴포넌트 속성 값 주듯이, 속성에 정해진 값을 전달하면 원하는 애니메이션을 구현할 수 있습니다!
2주차 끝 & 숙제 설명 ❓❗스파르타 코딩 이름에 걸맞게 앱 디자인을 이번 주차에 완벽히 끝내려 합니다! 1) 마이페이지와 디테일 페이지를 구현해보시기 바랍니다😎 연습만이 살길! 2) 추가적으로 MainPage에서 카드를 눌렀을 때 데이터도 넘겨보시길 바라요! 넘긴 데이터가 DetailPage에 보이게끔!
👉 마이페이지가 가장 챌린지급 예제가 될 것으로 예상되는데요! <- 쌤 진짜 어려워요...............
1) flexWrap: 'wrap' 2) ImageBlurLoading 를 적절히 사용하여 구현해보시기 바랍니다!
ImageComponent를 만들어서 구현해보면 컴포넌트에 대한 확실한 연습이 될 것 같네요 🙂
디테일 페이지에서는 NativeBase의 ListItem을 이용해서 댓글 리스트를 한번 구현해보시기 바랍니다. 각 댓글들은 역시나 컴포넌트로 만들어야 효율적이겠죠?
즉, Mypage를 만들땐 Components 폴더에 ImageComponent.jsx를 생성해서 구현해보고! DetailPage를 만들땐 CommentComponent.jsx 컴포넌트를 만들어서 댓글 리스트를 구현해보세요! 썸네일에 사용된 square2주차 수강 후기 기획한 앱에 생각보다 많은 기능이 들어가게 된 다는 것,, 앱 구현이 쉽지않은^^..일이라는 것,,, 조금더 공부 열심히 해야겠다.. 내가 만들어야 할 앱 개발 하면서 다시 수강하게 될 듯^_ㅠ