App.js
HomeScreen.js
navigate
의 두 번째 인자로 route 객체를 넘긴다.
DetailScreen.js
HomeScreen에서 클릭하면 Detail로 넘어가는데 route.params
에서 정의한 데이터를 가지고 가게 된다!
이렇게 차곡차곡 stack에 쌓인다.
CreatePostScreen.js
버튼을 누르면 setPostText
에 담긴 data가 params 객체로 넘어가게 된다.
HomeScreen.js
마찬가지로 Home에서 route의 객체를 받는다., useEffect를 이용해서 updated가 되는지 확인해보자!
navigation이 작동할 때마다 의존성 배열에 정의한 route 객체가 달라져서 업데이트가 작동한다!
App.js
options에 조금 장난을 친다. title을 route.params.name
이라고 정의하고 Profile을 컴포넌트를 만든다.
ProfileScreen.js
HomeSreen.js
그리고 Home에서 params 객체로 name을 설정해준다!
Profile 컴포넌트가 Home에서 params로 지정해둔 title로 되었다!
이렇게 setOption
을 통해 업데이트도 할 수 있다! 그렇다면 이제 option을 이용해서 style을 바꿔보자!
요렇게 options의 프로퍼티로 style을 줄 수 있다!
또한, title 부분을 커스텀 가능하다. 예를들어 LogoTitle이라는 컴포넌트를 만들고
App.js
headerTitle를 통해 아예 컴포넌트 통으로 주는 건데 조금 어색했다.
You might be wondering, why headerTitle when we provide a component and not title, like before? The reason is that headerTitle is a property that is specific to a stack navigator, the headerTitle defaults to a Text component that displays the title.
출처: https://reactnavigation.org/docs/headers
headerTitle 프로퍼티는 text 컴포넌트를 title로 쓰는 특수한 프로퍼티라서 컴포넌트를 통으로 준다고 한다!
App.js
요렇게 headerRight라는 프로퍼티에 Button 컴포넌트를 주게 되면
깜찍 그자체다.
HomeScreen.js
조금 고급 기술이 들어간다. 일단 대충 보아하니 headerRight가 있고 button을 누르면 count가 올라가는 구조다.
특이한 점은 useLayoutEffect
란 이름부터 UI 업데이트와 관련있을 것 같은 함수에 navagation.setOption
이 콜백으로 들어가고 인자로 객체가 있고headerRight
가 프로퍼티에 밸류는 콜백, 그리고 Button 컴포넌트가 있다. 마지막으로 의존성 배열에는 navigation. 구조 진짜 어렵다.
이렇게 header에서 이벤트를 만들어서 screen에 영향도 줄 수 있는 것!
진짜 핵심이다. 내가 알고 싶었던 navigator로 중첩해서 장난치기. 이제 시작!
이런 구조가 있다고 가정하다. 여기서 Home 컴포넌트는 tab navigator를 가지고 있다. 또한 Home 컴포넌트는 App 컴포넌트의 stack안에 있기도 하다. 즉, stack navigator안에 tab navigator가 있는 구조다.
출처 : https://reactnavigation.org/
이제 우리는 몇 가지를 고려해야 한다!
각 navigator는 자신만의 navigation history를 가진다.
각 navigator는 자신만의 options을 가진다.
각 navigator는 자신만의 params를 가진다.
navigation의 액션은 현재 navigator에 의해 작동한다.
navigator의 특정 메서드는 nasted된 navigator 안에서만 사용 가능하다.
nested된 navigator는 부모의 이벤트를 받지 않는다.
부모 navigator의 UI는 child navigator의 최상단에서 렌더된다 (뭔말이여)
이제 예제를 보자!!
App.js
Root.js
<Drawer.Navigator>
를 만들고 Root, Home 컴포넌트를 stack에 쌓았다. Root 컴포넌트에는 또 다른 screen들이 있는데 Home에서 Root로 어떻게 navigate를 할까. 그리고 Root 안에 있는 다른 screen에 어떻게 접근할까? 예를들어 Root 컴포넌트는 Profile을 initial screen로 보여주는데 Home에서 SettingScreen으로 어떻게 접근할까?
방법은 또 params!
Home.js
요렇게 장난을 쳐주면 Home에서도 접근이 가능해진다.
navigation.navigate('Root', {
screen: 'Settings',
params: { user: 'jane' },
});
screen과 params 프로퍼티로 중첩 navigator를 마음껏 접근 가능하다.
Setting.js
navigator가 여러 개 중첩된다면!? 생각만해도 설렌다. 어서 해결해보자.
이렇게 여러 navigator가 중첩되어 있으면 header 중복이 일어나는데 (아직까진 정확히 모름) headerShown: false
이렇게 해결할 수 있다!
중첩이 많으면 퍼포먼스가 안좋아진다. 같은 타입의 navigators는 UX의 혼란을 준다. 가독성이 떨어진다. 아래처럼 nesting을 스마트하게 해보자.
Navigation도 생명주기가 있다. stack에 넣었다가 뺐다 하면 어떻게 컴포넌트가 나타나고 사라지는 걸까? 무척 궁금해진다.
예를들어 screen A와 B가 있다고 하자. A로 이동하면 CDM(componentDidMount)가 실행된다. 혹은 B로 가면 CDM이 실행된다. 하지만 A는 아직 stack에 남아있기 때문에 CWU(componentWillUnmount)는 실행되지 않는다.
하지만 B에서 A로 이동하면 B의 CWU가 실행된다. 하지만 A의 CDM은 A가 stack에 있다고 해서 계속 실행되지 않는다.
App.js
이런 App이 있다고 가정하자. Tab.Navigator
에 두 개의 Tab.Screen>
이 있고 각각 HomeStack
과 SettingStack
이 있다.
navigation의 생명주기를 이해하기 위해서 가장 중요한 것은 focus
와 blur
다!
Profile.js
profile 컴포넌트가 사라지고 나타날 때마다 navigation에 이벤트 리스너를 걸어서 확인해보자. console이 잘 작동하는 것을 알 수 있다!
Modal은 Navigation의 흐름이 아니다! 갑자기 Modal을 넣어야 할 때 어떻게 대처할 것인가? 이제 Stack의 마지막, Modal에 대해 알아보자!!!
App.js
출처 : https://reactnavigation.org/docs/modal/
요런 구조로 되어있다! RootStack.Navigator
에 prop으로 mode에 modal 컴포넌트를 주었다. stack navigator안에 또 다른 stack navigator를 넣을 수 있기 때문에 가능한 일이다!
(조금 헷갈림)
To change the type of transition on a stack navigator you can use the mode prop. When set to modal, all screens animate-in from bottom to top rather than right to left. This applies to that entire stack navigator, so to use right to left transitions on other screens, we add another navigation stack with the default configuration.
navigation.navigate traverses up the navigator tree to find a navigator that can handle the navigate action.
그니까... mode prop으로 modal을 가능하게 했다... 그런 뜻이다!