65일차 TIL : 리액트 네이티브

변시윤·2023년 1월 3일
0

내일배움캠프 4기

목록 보기
67/131

학습내용

  • 명령어로 프로젝트-expo 연결
  • react-navigation
  • useEffect vs useFocusEffect
  • 다크/라이트 모드

명령어로 프로젝트 expo에 연결하기

  1. eas update:configure
  2. Would you like to autoimatically create an EAS project for (@유저네임/프로젝트명)? ➡️ Y

미로그인 상태라면 2번 전에 ID/비밀번호 우선 입력



react-navigation

라우팅 기능과 네비게이션 레이아웃을 제공하는 리액트 네이티브의 라이브러리

  • 기본 설치
    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과 Native Stack

프로젝트에 사용된 페이지들(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>
  );
};
-StackNative Stack
특징자바스크립트로 구현iOS와 안드로이드의 네이티브 모듈 참고
퍼포먼스-우세
기능-iOS 큰 제목 기능 제공
사용자 정의우세-

Navigation prop을 참고하면 기본적인 기능 이외에도 별도의 옵션을 추가할 수 있다.

Bottom Tabs

스크린 하단에 위치하는 네비게이터

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등의 네비게이터를 제공한다.



useEffect와 useFocusEffect

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>
  );
}
-useEffectuseFocusEffect
제공React HookReact Native Hook
감지 시기Mount, Unmount, dependency값 변경Focus, Blur
화면 이탈시렌더링 결과 보유Blur 처리



다크/라이트 모드

셋업

  • 초기 설정
    app.json에서 expo의 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>
  );
}
  • NavigationContainer
    전반적인 모드 전환. ThemeProviderNavigator에 별도의 테마 적용시 설정할 필요 X
  • ThemeProvider

    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,
          }}
        >
        )

    각각의 네비게이터의 테마 설정

profile
개그우먼(개발을 그은성으로 하는 우먼)

0개의 댓글