TIL : React Navigation

hihyeon_cho·2023년 1월 3일
0

TIL

목록 보기
47/101
post-thumbnail

React Navigation

:routing 하기 위해서 사용하는 라이브러리로, react의 react-router-dom역할을 하는데, routing 뿐만아니라 navigation을 위한 레이아웃도 제공한다.

React Navigation 설치하기

yarn add @react-navigation/native

npx expo install react-native-screens react-native-safe-area-context


Native Stack

설치하기

yarn add @react-navigation/native-stack

사용하기

import { NavigationContainer } from "@react-navigation/native";
import { createNativeStackNavigator } from "@react-navigation/native-stack";

const Stack = createNativeStackNavigator();

const One = ({ navigation: { navigate, setOptions } }) => {
  return (
    <>
      <TouchableOpacity onPress={() => navigate("two")}> {/*Two로 이동*/}
        <Text>Two</Text>
      </TouchableOpacity>
      <TouchableOpacity
        onPress={() =>
          setOptions({
            title: "2!",
          })
        } // title 변경
      >
        <Text>change</Text>
      </TouchableOpacity>
    </>
  );
};
const Two = ({ navigation: { goBack, reset } }) => {
  return (
    <>
      <TouchableOpacity onPress={() => goBack()}> {/*이전으로*/}
        <Text>Back</Text>
      </TouchableOpacity>
      <TouchableOpacity
        onPress={() =>
          reset({
            index: 0,
            routes: [{ name: "one" }],
          }) //초기 화면으로 이동, 히스토리 삭제 
        }
      >
        <Text>Reset navigation</Text>
      </TouchableOpacity>
    </>
  );
};

react navigation을 사용하기 위해서 최상단에 <NavigationContainer>로 감싸줘야한다

<NavigationContainer>
      {/* <Stack.Navigator initialRouteName="two"> 
      	=> 초기화면 설정 */}
      <Stack.Navigator
        screenOptions={{
          headerTintColor: "red", 
            // header 글자색 바꾸기
          headerBackTitle: "이전으로", 
            // 이전 히스토리로 넘어가는 제목 바꾸기
          presentation: "modal", 
            // 다음 창 모달로 띄우기
          animation: "flip", 
            //filp 애니메이션 넣기
        }} 
        //전체적으로 속성을 적용하기 위해 screenOptions를 사용한다.
      >
        {/*컴포넌트 넣기*/}
        <Stack.Screen name="one" component={One} /> 
       	<Stack.Screen
          options={{
            presentation: "fullScreenModal",
          }} 
          name="two"
          component={Two}
        />
        {/*속성을 하나의 컴포넌트에만 적용하고 싶을때에는 options를 사용*/}
      </Stack.Navigator>
    </NavigationContainer>

Bottom Tabs

설치하기

yarn add @react-navigation/bottom-tabs

사용하기

import { createBottomTabNavigator } from "@react-navigation/bottom-tabs";
import Movies from "../screen/Movies";
import My from "../screen/My";
import { MaterialIcons } from "@expo/vector-icons";
import { Ionicons } from "@expo/vector-icons";

const Tab = createBottomTabNavigator();

export default function BottomTabs() {
  return (
    <Tab.Navigator
      initialRouteName="My" //초기 라우터 설정값
      sceneContainerStyle={{ backgroundColor: "plum" }} //배경색
      screenOptions={{ tabBarLabelPosition: "beside-icon" }} //tabBarLabel 글씨위치
    >
      <Tab.Screen
        options={{
          title: "영화", //제목
          headerTitleAlign: "left",// 제목 정렬
          tabBarLabel: "Movies",//tabbar에 표시될 글씨
          tabBarIcon: ({ color, size }) => (
            <MaterialIcons name="local-movies" size={size} color={color} />
          ), //tabBarIcon은 프롭스내용을 인자로 받는 콜백함수로 적용한다.
        }}
        name="Movies"
        component={Movies} //컴포넌트 넣기
      />
      <Tab.Screen
        options={{
          title: "내가 작성한 댓글",
          tabBarLabel: "My",
          tabBarBadge: 1, //tabbar 뱃지. 문자열도 가능
          tabBarIcon: ({ color, size }) => (
            <Ionicons name="person" size={size} color={color} />
          ),
        }}
        name="My"
        component={My}
      />
    </Tab.Navigator>
  );
}


useFocusEffect

: react-navigation에서 제공하는 Hook.
useEffect와 유사하지만 다른 점은 useCallback이라는 함수를 인자로 받는다는 것이다.

useCallback이라는 함수는 콜백함수와 dependency array(의존성 배열)을 인자로 받는 useEffect와 같은 원리를 가진 함수이다.

웹은 화면을 벗어나면 랜더링한 결과를 기억하지 않고, 언마운트 되지만,

앱은 화면을 벗어나도 언마운트 되지 않고, 랜더링 된 결과를 그대로 가지고 있다.

이때, 앱을 언마운트 시키려면 reset 메서드를 이용(navigation stack을 초기화하는 역할)해야한다.

useEffect(() => {
    console.log("마운트"); //랜더링 되어 화면에 띄워졌을 때,
    return () => {
      console.log("언마운트"); //화면으로부터 벗어나서 랜더링 하지 않을 때,
    };
  }, []); // 의존성 배열로 빈배열 추가하면 처음 랜더링할때 한번만 랜더링 됨

useFocusEffect(
	useCallback(()=>{  //useFocusEffect는 useCallback이라는 함수를 인자로 받음
    console.log("Focus"); // 화면이 눈에 보일 때,
    return ( )=> {
        console.log("Blur"); //화면이 눈에 안보일 때,
    };
  },[]) // useCallback의 인자는 콜백함수와 dependency array이다. // useEffect와 같은 원리
  );

Dark모드 컨트롤하기

( 참고 : expo 공식문서 )

  1. app.json에서 "userInterfaceStyle"을 "automatic"으로 변경한다.
  2. react native hook인 useColorScheme을 이용하여 dark모드를 판별한다.
const isDark = useColorScheme() === "dark";
//dark모드일 경우 true를 반환
  1. NavigationContainer에 theme속성으로 navigation에서 제공하는 DarkTheme, DefaulTheme를 적용한다.

  2. 각각의 컴포넌트에서도 isDark를 이용하여 darktheme일 때의 색상을 컨트롤 할 수 있다.

ThemeProvider ? ( emotion )

제일 바깥 (<NavigationContainer>밖 )을 ThemeProvider로 감싸게 되면 ThemeProvider에 theme를 지정할 수 있다.

<ThemeProvider theme={}>
  <NavigationContainer>
  ...
</ ThemeProvider> 

그러면 styledComponents를 쓸 때, props.theme로 theme안에 있는 객체로 어디서든 자유롭게 접근 할 수 있게 된다.

profile
코딩은 짜릿해 늘 새로워 ✨

0개의 댓글