230103_TIL

·2023년 1월 4일

React Native

Keyboard.dismiss()

  • <Textinput>에 내용을 적을 시, 키보드가 튀어나오는데 해당 메소드를 쓰면 해당 내용을 작성하고 등록시, 키보드가 자동으로 사라짐.

    Logic
    글 등록 -> 등록 버튼 클릭 -> 글이 등록되면서 모바일 키보드가 내려감.

React Navigation

expo에서 Routing 뿐만 아니라, navigation 레이아웃을 지원해주는 라이브러리다. sidebar, modal, deep linking 등등..

native stack navigator

  • 적용하려는 컴포넌트의 최상단에 차지하고 있어야 한다.
    navigate props 종류
    ✅ 잘 쓰이는 속성 : navigate, reset, goBack, setOptions
import { StatusBar } from "expo-status-bar";
import { StyleSheet, Text, TouchableOpacity, View } from "react-native";
import { createNativeStackNavigator } from "@react-navigation/native-stack";
import { NavigationContainer } from "@react-navigation/native";

const Stack = createNativeStackNavigator();

// {navigation : {navigate}} << 지정한 컴포넌트로 이동하기. 해당 코드에서는 two 컴포넌트로 갈 것이다.
const One = ({ navigation: { navigate } }) => {
  return (
    <TouchableOpacity
      onPress={() => {
        return navigate("two");
      }}>
      <Text>One</Text>
    </TouchableOpacity>
  );
};
const Two = ({ navigation: { navigate, setOptions } }) => {
  return (
    <>
      <TouchableOpacity onPress={() => navigate("three")}>
        <Text>Two</Text>
      </TouchableOpacity>
      <TouchableOpacity
        onPress={() => setOptions({ title: "Hello, Jane Doe" })}>
        <Text>Set Options</Text>
      </TouchableOpacity>
    </>
  );
};
const Three = ({ navigation: { goBack, reset } }) => {
  // 뒤로가기 속성 : goBack
  return (
    <>
      <TouchableOpacity onPress={() => goBack()}>
        <Text>Three</Text>
      </TouchableOpacity>
      <TouchableOpacity
        onPress={() => reset({ index: 0, routes: [{ name: "two" }] })}>
        {/*reset은 navigation history 자체를 싹 다 밀어버림. history가 남아있는 경우, two에서 one으로 갈 수 있지만, 싹 다 밀어버렸기 때문에 two에서 뒤로가기 버튼이 없어짐.*/}
        <Text>Reset Navigation</Text>
      </TouchableOpacity>
    </>
  );
};

export default function App() {
  return (
    <NavigationContainer>
     {/* initialRouteName는 첫 로딩이 끝나고, 화면에 표시되는 페이지를 지정. */}
      {/*(<Stack.Navigator initialRouteName="three">*/}

      {/* screenOptions 는 객체를 인자로 받음.*/}
      <Stack.Navigator
        screenOptions={{
          headerTintColor: "red", // 헤더부분 색상 변경 속성
          headerBackTitle: "뒤로 오십셔", // 뒤로가기 title 변경
          presentation: "modal", // 페이지 이동 시, 모달형식으로 뜨게 할 지
          animation: "flip", // 카드 형식으로 페이지 이동 효과 애니메이션
        }}>
        <Stack.Screen name="one" component={One} />
        <Stack.Screen name="two" component={Two} />
        <Stack.Screen
          options={{ presentation: "modal" }} 
          // 개별적으로 option을 줄 수 있음.
          // 일괄적으로 하려면 감싸고 있는 <Stack.Navigator>에 screenOptions={{ ... }} 적용.
          name="three"
          component={Three}
        />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

// <Stack.Screen>에 props로 들어가는 컴포넌트를 '스크린 컴포넌트'라고 지칭한다.
// 해당 컴포넌트들은 기본적으로 navigation을 props를 가진다..

reset 속성 어떨때, 왜 사용하는가?

참고 블로그
React Native 프로젝트에서 React Navigation 중 Stack Navigation 을 사용하면 스택이 계속 쌓인다. 이 때 스택을 초기화 해야하는 경우가 있다. 대표적으로 step을 밟으면서 회원가입을 할 경우! 회원가입이 끝나고 난 뒤에도 뒤로가기를 했을때 회원가입 중인 페이지를 안 보이게 하려면 스택을 초기화해야한다.

  • 사용 방법
navigation.reset({routes: [{name: "welcome", params: { email, password }}]})

// name 옆에는 지정해준 컴포넌트 이름, params 에는 다음 페이지로 보내줄 변수들을 입력. prams는 선택사항.

import React from 'react';
import {StyleSheet, View, Text, Button} from 'react-native';

export default ({navigation}) => {
  return (
    <View style={styles.container}>
      <Text style={styles.text}>세번째 페이지입니다.</Text>
// ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡreset
      <Button
        onPress={() => navigation.reset({routes: [{name: 'last'}]})}
        title="다음 페이지로"
        color="#999"
      />
// ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
    </View>
  );
};

sceneContainerStyle{ {} }

  • 스크린 화면에 대한 스타일링을 할 수 있는 속성.
  • 객체를 인자로 받음.
import { createBottomTabNavigator } from "@react-navigation/bottom-tabs";
import React from "react";
import { Text, TouchableOpacity, View } from "react-native";
import Movies from "../screen/Movies";
import My from "../screen/My";

const Tab = createBottomTabNavigator();

export default function Tabs() {
  return (
    <Tab.Navigator
//ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ sceneContainerStyle 적용 예시 code
      sceneContainerStyle={{
        backgroundColor: "skyblue",
      }}
//ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
  
//ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ screenOptins={{}} 적용 예시 code.
      screenOptions={{
        headerRight: () => (
          <TouchableOpacity>
            <Text style={{ color: "black" }}>햄버거버튼</Text>
          </TouchableOpacity>
        ),
      }}>
//ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
      <Tab.Screen
		options={{
          title: "Moive List", // header 이름 설정
          tabBarLabel: "Recommend", // Tab 이름 설정
        }}
        name="Movies Selector"
        component={Movies}
      />
      <Tab.Screen name="My Page" component={My} />
    </Tab.Navigator>
  );
}

screenOptions={{}} 속성, tabBarLabelPosition

  • TabBar의 위치를 row, colunm으로 결정 가능.
export default function Tabs() {
  return (
    <Tab.Navigator
      screenOptions={{
        tabBarLabelPosition: "beside-icon", // "below-icon" 두 가지가 있음,
      }}>
      <Tab.Screen
        options={{
          title: "Moive List",
          tabBarLabel: "Recommend",
        }}
        name="Movies Selector"
        component={Movies}
      />
      <Tab.Screen name="My Page" component={My} />
    </Tab.Navigator>
  );
}

tabBarIcon

사용 예시

	<Tab.Screen
        options={{
          title: "Moive List",
          tabBarLabel: "Recommend",
//ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ options={{}} 속성 중 하나.
          tabBarIcon: (color, size) => (
            <MaterialIcons name="movie-filter" size={32} color={"red"} />
          ),
//ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ tabBarIcon : () => {return } // return은 중괄호와 함께 생략가능.
        }}
        name="Movies Selector"
        component={Movies}
	/>

tabBarBedge

상태이상 알림 뱃지

<Tab.Screen
        name="My Page"
        component={My}
        options={{
          tabBarIcon: (color, size) => (
            <Feather name="user" size={32} color={"red"} />
          ),
//ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ tabBarBedge
          tabBarBadge: "3", // 상태이상 알림 뱃지
        }}
      />

Stack Navigator & Bottom Tab 병합 사용

import React from "react";
import { createNativeStackNavigator } from "@react-navigation/native-stack";
import { Text, TouchableOpacity, View } from "react-native";
import Stacks from "./Stacks";
import Tabs from "./Tabs";

const Stack = createNativeStackNavigator();

export default function Root() {
// ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ여기 코드 !
  return (
    <Stack.Navigator screenOptions={{ headerShown: false }}> {/*Tabs의 헤더를 감춰줌*/}
      <Stack.Screen name="Tabs" component={Tabs} />
      <Stack.Screen name="Stacks" component={Stacks} />
// ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡComponent Stack의 Screen Component인 Tabs / Stacks를 Root Component로 한 번에 불러옴.
    </Stack.Navigator>
  );
}

서로 다른 컴포넌트로 화면 이동

import React from "react";
import { Text, TouchableOpacity, View } from "react-native";

export default function Movies({ navigation: { navigate } }) {
  return (
    <View>
      <Text>Movies</Text>
//ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ여기 코드 !
      <TouchableOpacity onPress={() => navigate("Stacks", { screen: "one" })}>
//ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡStacks 컴포넌트의 one screen 컴포넌트 화면으로 간다 !
        <Text>Go To One Screen</Text>
      </TouchableOpacity>
    </View>
  );
}

<TouchableOpacity onPress={() => navigate("Stacks", { screen: "one" })}>

코드 요약 : navigate("보여줄 screen component가 있는 component", {"보여줄 screen component : name 속성 기입."})

컴포넌트 이동 시, prams 넘겨주고, 받는 방법

  • prams 보내는 컴포넌트의 코드
import React from "react";
import { Text, TouchableOpacity, View } from "react-native";

export default function Movies({ navigation: { navigate } }) {
  return (
    <View>
      <Text>Movies</Text>
//ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ여기 코드 !
      <TouchableOpacity
        onPress={() =>
          navigate("Stacks", { screen: "one", params: { id: "ONESCREEN" } })
        }>
//ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ 버튼 클릭 시, one screen component에 id값을 담아 보낸다 !
        <Text>Go To One Screen</Text>
      </TouchableOpacity>
    </View>
  );
}
  • prams 받는 컴포넌트의 코드
// 여기 코드 !
const One = ({ route: { params }, navigation: { navigate } }) => {
// 인자로 {route : {params} } 해주면 보내준 params를 받을 수 있다 !
  console.log("====================================");
  console.log(params); // 제대로 받았나 확인..
 console.log("====================================");
  return (
    <TouchableOpacity
      onPress={() => {
        return navigate("two");
      }}>
      <Text>One</Text>
    </TouchableOpacity>
  );
};

useEffect와 useFocusEffect 차이 (React) vs (React Native)

  • useEffect
    - 화면에서 사라지면 바로 Unmount 된다. (기록이 사라짐)

  • useFocusEffect
    - 화면에서 사라져도 Unmount되지 않고, Mount 되었던 기록이 남아있음.
    - Unmount 시키려면, reset속성을 이용해서 초기화시켜주어야 한다.
    • useFocusEffect는 useCallback이라는 메소드가 또 들어간다.
// useFocusEffect는 useCallback이라는 메소드가 또 들어간다. 
useFocusEffect(
	useCallback( () => {
	console.log("Focus");
  	return () => {
      console.log("Blur")
    };
}, [] )
)
  • 참고 예시 코드
const Three = ({ navigation: { goBack, reset } }) => {
  return (
    <View>
      <TouchableOpacity onPress={() => goBack()}>
        <Text>Three</Text>
      </TouchableOpacity>
//ㅡㅡㅡㅡㅡㅡㅡㅡreset 여기 !
      <TouchableOpacity
        onPress={() => reset({ index: 0, routes: [{ name: "one" }] })}>
//ㅡㅡㅡㅡㅡㅡㅡㅡreset 여기 !
{/*reset은 navigation history 자체를 싹 다 밀어버림.
예시 : history가 남아있는 경우, one -> two로 화면 이동했다는 가정하에, two에서 다시 one으로 갈 수 있지만, 싹 다 밀어버렸기 때문에 two에서 뒤로가기 버튼이 없어짐.*/}
        <Text>Reset Navigation</Text>
      </TouchableOpacity>
    </View>
  );
};

Dark Mode

app.json에서 "expo"의 value값 중에 "userInterfaceStyle": "automatic", 이렇게 바꿔줘야 한다. default값은 light로 되어있음.

  • emulator에서 darkMode 확인 : shift + cmd + a

  • 예제코드

import { useColorScheme } from "react-native";
import {
  DarkTheme,
  DefaultTheme,
  NavigationContainer,
} from "@react-navigation/native";

import Root from "./navigation/Root";

export default function App() {
//ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡuseColorScheme() 메서드 활용.
  const isDark = useColorScheme() === "dark";
  console.log("isDark : ", isDark);
  return (
    <NavigationContainer theme={isDark ? DarkTheme : DefaultTheme}>
//ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡisDark가 true이면 다크모드, 아니면 일반 모드
      <Root />
    </NavigationContainer>
  );

Javascript

splice()

findindex()

profile
- 배움에는 끝이 없다.

0개의 댓글