Skip to content

React Native โ€‹

ReactNative CLI ์„ค์น˜ ๋ฐ ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ โ€‹

shell
npx @react-native-community/cli@latest init AwesomeProject
  • Vscode Terminal์— ์œ„ ๋ช…๋ น์–ด ์‹คํ–‰ํ•˜์—ฌ ์ƒˆ ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ
  • File > Add Folder to Workspace ์„ ํƒ ํ›„ ํ”„๋กœ์ ํŠธ๋ฅผ ์›Œํฌ์ŠคํŽ˜์ด์Šค์— ์ถ”๊ฐ€

ํ”„๋กœ์ ํŠธ ๋””๋ ‰ํ† ๋ฆฌ๋กœ ์ด๋™ โ€‹

shell
cd /๊ฒฝ๋กœ/ํ”„๋กœ์ ํŠธํด๋”
  • ์ƒ์„ฑ๋œ ํ”„๋กœ์ ํŠธ ํด๋”๋กœ ์ด๋™

๊ฐœ๋ฐœ ์„œ๋ฒ„ ๋ฐ ์•ฑ ์‹คํ–‰ โ€‹

shell
npm start
  • Metro ๋ฒˆ๋“ค๋Ÿฌ๋ฅผ ์‹œ์ž‘ (React Native์˜ JavaScript ๋ฒˆ๋“ค๋Ÿฌ)
  • ์ฝ”๋“œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ๊ฐ์ง€ํ•˜๊ณ  ์ž๋™์œผ๋กœ ์•ฑ์„ ์ƒˆ๋กœ๊ณ ์นจ
  • ๋””๋ฒ„๊น… ์ฝ˜์†”์„ ์ œ๊ณต
  • ์•ฑ์„ iOS๋‚˜ Android ๊ธฐ๊ธฐ/์—๋ฎฌ๋ ˆ์ดํ„ฐ์— ์—ฐ๊ฒฐํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•จ
    (npm start๋Š” ๋ฒˆ๋“ค๋Ÿฌ๋งŒ ์‹คํ–‰ํ•˜๋Š” ๋ช…๋ น์–ด์ด๊ณ , ์•ฑ ์‹คํ–‰๊นŒ์ง€ ํฌํ•จํ•˜๋ ค๋ฉด npm ios, npm ios์ถ”๊ฐ€ ๋ช…๋ น์ด ํ•„์š”)

shell
npm run ios
  • ios ์‹œ๋ฎฌ๋ ˆ์ดํ„ฐ์—์„œ ์•ฑ ์‹คํ–‰

shell
npm run android
  • android ์• ๋ฎฌ๋ ˆ์ดํ„ฐ์—์„œ ์•ฑ ์‹คํ–‰

ReactNative Expo ์„ค์น˜ ๋ฐ ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ โ€‹

expo ๊ณต์‹ ๋ฌธ์„œ โ€‹

https://docs.expo.dev/get-started/create-a-project/

shell
npx create-expo-app@latest
  • expo์—์„œ ์ œ๊ณตํ•˜๋Š” ํ…œํ”Œ๋ฆฟ์œผ๋กœ ํ”„๋กœ์ ํŠธ๊ฐ€ ๋งŒ๋“ค์–ด์ง

https://docs.expo.dev/get-started/set-up-your-environment/

  • ํ™˜๊ฒฝ์„ค์ •
shell
npx install
shell
npx expo start

Component โ€‹

ios SafeAreaView โ€‹

Pressable โ€‹

tsx
<Pressable onPress={onPressFunction}>
  <Text>I'm pressable!</Text>
</Pressable>
  • https://reactnative.dev/docs/pressable
  • ๋ฒ„ํŠผ์ด ์•„๋‹Œ ์–ด๋–ค ๋ˆŒ๋Ÿฌ์•ผ ํ•˜๋Š” ์˜์—ญ์„ ๊ตฌํ˜„ํ•  ๋•Œ pressable ์‚ฌ์šฉ
  • pressable๋กœ ํ…์ŠคํŠธ๋ฅผ ๊ฐ์‹ธ๊ฒŒ ๋˜๋ฉด ๋ฒ„ํŠผ ์ปดํฌ๋„ŒํŠธ์ฒ˜๋Ÿผ onpress์„ ์ด์šฉํ•ด์„œ ํ•ธ๋“ค๋Ÿฌ๋ฅด ์—ฐ๊ฒฐํ•ด์ค„ ์ˆ˜ ์žˆ์Œ
  • TouchableOpacity, TouchableWithoutFeedback๋„ ์žˆ์ง€๋งŒ ๊ณต์‹๋ฌธ์„œ์—์„œ๋„ Pressable์„ ์ถ”์ฒœํ•˜๊ณ  ์žˆ์Œ, ๊ฐ€์žฅ ์ตœ๊ทผ์— ๋‚˜์˜จ ์ปดํฌ๋„ŒํŠธ์ด์ž ๋” ๋””ํ…Œ์ผํ•œ ๋™์ž‘๋“ค์„ ์ œ์–ด๊ฐ€๋Šฅ

TouchableOpacity โ€‹

TouchableWithoutFeedback โ€‹

expo ํŒŒ์ผ๊ธฐ๋ฐ˜ ๋ผ์šฐํŒ… โ€‹

-ํด๋”์™€ ํŒŒ์ผ๋ช…์ด ๊ฒฝ๋กœ๊ฐ€ ๋œ๋‹ค. ์ธ๋ฑ์Šค ๊ฐ™์€ ๊ฒฝ์šฐ์—๋Š” ๊ฒฝ๋กœ๊ฐ€ /์ด๊ณ 

expo vector icons โ€‹

ex ์˜ˆ์‹œ

shell
<Tabs.Screen
  name="index"
  options={{
    title: "ํ™ˆ",
    tabBarIcon: ({ color, focused }) => (
      <Ionicons
        name={focused ? "home-sharp" : "home-outline"}
        size={24}
        color={color}
      />
    ),
  }}
/>

๋งค๊ฐœ๋ณ€์ˆ˜ focused์˜ ๊ฐ’์— ๋”ฐ๋ผ ์•„์ด์ฝ˜์„ ๋‹ค๋ฅด๊ฒŒ ๋ณด์—ฌ์ฃผ๊ธฐ ์œ„ํ•ด ์‚ผํ•ญ ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉ. focused๊ฐ€ true๋ฉด "home-sharp", false๋ฉด "home-outline"์„ ๋ฐ˜ํ™˜.

FlatList โ€‹

  • https://reactnative.dev/docs/flatlist
    FlatList๋Š” React Native์—์„œ ์Šคํฌ๋กค ๊ฐ€๋Šฅํ•œ ๋ชฉ๋ก์„ ํšจ์œจ์ ์œผ๋กœ ๋ Œ๋”๋งํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ฃผ๋Š” ์ปดํฌ๋„ŒํŠธ. ํŠนํžˆ ๋ฐ์ดํ„ฐ๊ฐ€ ๋งŽ๊ฑฐ๋‚˜ ํ•ญ๋ชฉ์˜ ๊ธธ์ด๊ฐ€ ๊ฐ€๋ณ€์ ์ธ ๊ฒฝ์šฐ, ์ตœ์ ํ™”๋œ ์„ฑ๋Šฅ์„ ์ œ๊ณตํ•˜๊ธฐ ๋•Œ๋ฌธ์— ScrollView๋ณด๋‹ค ๊ถŒ์žฅ๋จ
  • ๋ฌดํ•œ ์Šคํฌ๋กค (Infinite Scroll)
    ์Šคํฌ๋กค์ด ๋ฐ”๋‹ฅ์— ๋‹ฟ์•˜์„ ๋•Œ onEndReached ์ด๋ฒคํŠธ๋ฅผ ํ™œ์šฉํ•ด ๋‹ค์Œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๋ฐฉ์‹์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋Š” ํŽ˜์ด์ง• ์ฒ˜๋ฆฌ๋‚˜ ์„œ๋ฒ„์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๋‚˜๋ˆ ์„œ ๊ฐ€์ ธ์˜ฌ ๋•Œ ์œ ์šฉํ•จ
  • ๋ Œ๋”๋ง ์ตœ์ ํ™”
    ๋ชจ๋“  ๋ฐ์ดํ„ฐ๋ฅผ ํ•œ ๋ฒˆ์— ๋ Œ๋”๋งํ•˜์ง€ ์•Š๊ณ , ํ™”๋ฉด์— ๋ณด์ด๋Š” ํ•ญ๋ชฉ๋งŒ ๋ Œ๋”๋งํ•˜๊ธฐ ๋•Œ๋ฌธ์— ํผํฌ๋จผ์Šค๊ฐ€ ํ›จ์”ฌ ์ข‹๋‹ค..๊ณ ํ•จ
  • ๊ณ ์ •๋œ ๋ ˆ์ด์•„์›ƒ or ๋™์  ๋ ˆ์ด์•„์›ƒ ๋ชจ๋‘ ๊ฐ€๋Šฅ
    ํ•ญ๋ชฉ์˜ ๋†’์ด๋‚˜ ๊ธธ์ด๊ฐ€ ์ผ์ •ํ•˜์ง€ ์•Š์•„๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, getItemLayout์„ ์‚ฌ์šฉํ•˜๋ฉด ์„ฑ๋Šฅ์„ ๋” ํ–ฅ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค.

React Hook Form โ€‹

shell
npm install react-hook-form

์˜ค๋ฅ˜๋“ค โ€‹

CoreSimulator ์„œ๋น„์Šค ๋ฒ„์ „ ๋ถˆ์ผ์น˜๋กœ ์ธํ•œ ์‹œ๋ฎฌ๋ ˆ์ดํ„ฐ ํ†ต์‹  ์˜ค๋ฅ˜ โ€‹

shell
CoreSimulator.framework was changed while the process was running.
Xcode.app was updated while the process was running.
Service version (1010.10) does not match expected (993.7)
  • Xcode๊ฐ€ ์‹คํ–‰ ์ค‘์ผ ๋•Œ macOS ๋˜๋Š” Xcode๊ฐ€ ์—…๋ฐ์ดํŠธ๋˜์—ˆ๊ฑฐ๋‚˜, Simulator ๊ด€๋ จ ํŒŒ์ผ์ด ๊ผฌ์ž„, ๊ทธ ๊ฒฐ๊ณผ๋กœ CoreSimulator ์„œ๋น„์Šค ๋ฒ„์ „ ๋ถˆ์ผ์น˜๋กœ ์ธํ•ด ์‹œ๋ฎฌ๋ ˆ์ดํ„ฐ์™€์˜ ํ†ต์‹ ์ด ์™„์ „ํžˆ ๋Š๊ธด ์ƒํƒœ
shell
killall Simulator

xcrun simctl shutdown all
xcrun simctl erase all
  • erase all์€ ๋ชจ๋“  ์‹œ๋ฎฌ๋ ˆ์ดํ„ฐ ์ดˆ๊ธฐํ™”๋จ.
  • ์ดํ›„ ์žฌ์‹คํ–‰ํ•˜๋‹ˆ๊นŒ ์ž‘๋™ํ–ˆ๋‹ค!!!

iOS/Android ์‹œ๋ฎฌ๋ ˆ์ดํ„ฐ ์‹คํ–‰ ์˜ค๋ฅ˜: bundleIdentifier์™€ package ์„ค์ • ํ•„์ˆ˜! โ€‹

์ฒ˜์Œ ํ”„๋กœ์ ํŠธ๋ฅผ ์„ค์ •ํ•  ๋•Œ app.json ๋˜๋Š” app.config.js ํŒŒ์ผ์—์„œ ์ด ๊ฐ’์„ ์ƒ๋žตํ–ˆ์—ˆ๋Š”๋ฐ, ์‹คํ–‰ ์‹œ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค:

shell
iOS: Missing bundleIdentifier

Android: Missing package name

ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์€ ๊ฐ„๋‹จํ•˜๋‹ค. app.json ํŒŒ์ผ์—์„œ ์•„๋ž˜์™€ ๊ฐ™์ด ์•ฑ์˜ ๊ณ ์œ  ์‹๋ณ„์ž๋ฅผ ์ถ”๊ฐ€ํ•˜๋ฉด ๋œ๋‹ค:

json
"ios": {
  "bundleIdentifier": "com.์‚ฌ์šฉ์ž์ด๋ฆ„.์•ฑ์ด๋ฆ„"
},
"android": {
  "package": "com.์‚ฌ์šฉ์ž์ด๋ฆ„.์•ฑ์ด๋ฆ„"
}

iOS ์‹œ๋ฎฌ๋ ˆ์ดํ„ฐ๋‚˜ Android Emulator์—์„œ ์•ฑ์„ ์‹คํ–‰ํ•˜๋ ค ํ•  ๋•Œ, bundleIdentifier (iOS)์™€ package (Android) ๊ฐ’์ด ์„ค์ •๋˜์ง€ ์•Š์œผ๋ฉด ์‹œ๋ฎฌ๋ ˆ์ดํ„ฐ๊ฐ€ ์•ฑ์„ ์‹คํ–‰ํ•˜์ง€ ๋ชปํ•˜๋Š” ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. ์ด ๊ฐ’๋“ค์€ ์•ฑ์˜ ๊ณ ์œ  ์‹๋ณ„์ž ์—ญํ• ์„ ํ•˜๋ฉฐ, ์‹ค์ œ ๋””๋ฐ”์ด์Šค๋‚˜ ์‹œ๋ฎฌ๋ ˆ์ดํ„ฐ์—์„œ ์•ฑ์„ ์‹คํ–‰ํ•˜๋ ค๋ฉด ๋ฐ˜๋“œ์‹œ ์„ค์ •ํ•ด์ค˜์•ผ ํ•œ๋‹ค.

TypeScript interface์™€ type โ€‹

interface, type์€ ๋‘˜ ๋‹ค ๋ฐ์ดํ„ฐ์˜ ๊ตฌ์กฐ๋ฅผ ์„ค๋ช…ํ•ด์ฃผ๋Š” ์„ค๋ช…์„œ์™€ ๊ฐ™์Œ

ts
// ์นœ๊ตฌ์˜ ์ •๋ณด๋ฅผ ๋‹ด์€ object๊ฐ€ ์žˆ๋‹ค๋ฉด, ์ด friend์• ๊ฐ€ ์–ด๋–ค ๊ตฌ์กฐ๋ฅผ ๊ฐ–๋Š”์ง€ ์„ค๋ช…ํ•  ์ˆ˜ ์žˆ์Œ

const friend = {
  name: "ํ›ˆ์ด",
  age: 30,
};
  • interface ์‚ฌ์šฉ ์˜ˆ์‹œ :
ts
interface Friend {
  name: string;
  age: number;
}
  • interface๋Š” ์ค‘๋ณต ์„ ์–ธ ๊ฐ€๋Šฅ
ts
interface Animal {
  name: string;
}

interface Animal {
  age: number;
}

// ์ด๋ ‡๊ฒŒ ๋‘ ๋ฒˆ ์„ ์–ธํ•˜๋ฉด ํ•ฉ์ณ์ ธ์„œ ์•„๋ž˜์ฒ˜๋Ÿผ ์ž‘๋™ํ•จ
// Animal = { name: string; age: number }
  • Type Alias ์‚ฌ์šฉ ์˜ˆ์‹œ :
ts
type Friend = {
  name: string;
  age: number;
};
  • type์€ ์ค‘๋ณต ์„ ์–ธ ์•ˆ ๋จ
ts
type Animal = {
  name: string;
};

type Animal = {
  age: number;
}; // ์—๋Ÿฌ, ๊ฐ™์€ ์ด๋ฆ„์œผ๋กœ ๋‘ ๋ฒˆ ์„ ์–ธํ•˜๋ฉด ์•ˆ๋จ
  • type์€ ์œ ๋‹ˆ์˜จ, ํŠœํ”Œ ๋“ฑ ๋” ๋‹ค์–‘ํ•œ ๊ฑธ ํ‘œํ˜„ ๊ฐ€๋Šฅ
ts
type Status = "success" | "error"; // ์œ ๋‹ˆ์˜จ
// ์—ฌ๋Ÿฌ ์„ ํƒ์ง€๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Œ

type Point = [number, number]; // ํŠœํ”Œ
  • ๊ทธ๋ž˜์„œ ์–ด๋–ค ๊ฒƒ์„ ์จ์•ผ ํ• ๊นŒ..?
  • ๋‹จ์ˆœํ•œ ๊ฐ์ฒด ๊ตฌ์กฐ๋งŒ ํ•„์š”ํ•˜๊ณ  ํ™•์žฅํ•  ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ๋‹ค๋ฉด interface
  • ๋‹ค์–‘ํ•œ ํƒ€์ž… ์กฐํ•ฉ(์œ ๋‹ˆ์˜จ, ํŠœํ”Œ ๋“ฑ)์ด๋‚˜ ๋ณต์žกํ•œ ๊ตฌ์กฐ๊ฐ€ ํ•„์š”ํ•˜๋‹ค๋ฉด type

์ด๋ฉ”์ผ ๊ฒ€์ฆ โ€‹

  • ์ด๋ฉ”์ผ regex ์ด๋ฉ”์ผ ์ •๊ทœ์‹ ๋“ฑ์˜ ํ‚ค์›Œ๋“œ๋กœ ์„œ์น˜

iosํ‚ค๋ณด๋“œ โ€‹

  • ios ์‹œ๋ฎฌ๋ ˆ์ดํ„ฐ์—์„œ ํ‚ค๋ณด๋“œ๊ฐ€ ์•ˆ ๋ณด์ผ ๊ฒฝ์šฐ Command + K
  • TextInput ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์‚ฌ์šฉ์ž์—๊ฒŒ ๋‹ค์–‘ํ•œ ํ˜•ํƒœ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ž…๋ ฅ๋ฐ›์„ ๋•Œ, ํ‚ค๋ณด๋“œ๊ฐ€ ์ž๋™์œผ๋กœ ์ ํ•ฉํ•œ ํ˜•ํƒœ๋กœ ๋‚˜ํƒ€๋‚˜๋„๋ก ํ•  ์ˆ˜ ์žˆ๋‹ค. ์˜ˆ์‹œ๋กœ, ์ด๋ฉ”์ผ์„ ์ž…๋ ฅ๋ฐ›์„ ๋•Œ ์ด๋ฉ”์ผ ์ „์šฉ ํ‚ค๋ณด๋“œ๋ฅผ ๋„์šฐ๊ฑฐ๋‚˜, ์ˆซ์ž ํ‚ค๋ณด๋“œ๋ฅผ ๋„์šธ ์ˆ˜ ์žˆ๊ณ , ํ‚ค๋ณด๋“œ์˜ ๋Œ€๋ฌธ์ž ํ™œ์„ฑ์„ ๋Œ ์ˆ˜ ์žˆ๋‹ค!
  • https://reactnative.dev/docs/textinput
  • https://www.lefkowitz.me/visual-guide-to-react-native-textinput-keyboardtype-options/
  • ํ‚ค๋ณด๋“œ ์œ„์ชฝ์— ์ŠคํŽ ์ฒดํฌ, ์ž๋™์™„์„ฑ ๊ฐ™์ด ๋œจ๋Š” ๋ถ€๋ถ„๋„
js
<TextInput
  placeholderTextColor={colors.GRAY_500}
  style={styles.input}
  autoCapitalize="none"
  spellCheck={false}
  autoCorrect={false}
  submitBehavior="submit" // ์ธํ’‹ ์ž…๋ ฅ ํ›„์—๋„ ํ‚ค๋ณด๋“œ ๋‚ด๋ ค๊ฐ€์ง€ ์•Š์Œ
  {...props}
/>

๋ฐฑ์—”๋“œ ์„œ๋ฒ„ ์‹คํ–‰ํ•˜๊ธฐ โ€‹

PgAdmin (https://www.pgadmin.org/) โ€‹

  • servers > register > server ๋“ฑ๋ก
  • ๋“ฑ๋กํ•œ ์„œ๋ฒ„์— database create
    ๋“ฑ๋ก ์‹œ .env์˜ DB_DATABASE์™€ ๊ฐ™์€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ช… ์ž…๋ ฅ
shell
// ์„œ๋ฒ„ ์‹คํ–‰
$ npm run start:dev

Postgresql (brew) (https://formulae.brew.sh/formula/postgresql@14) โ€‹

shell
// ์„ค์น˜
$ brew install postgresql@14

// ์„ค์น˜ ํ™•์ธ
$ brew list

// ์‹คํ–‰ ๋ช…๋ น์–ด
$ brew services start postgresql@14

๋กœ๊ทธ์ธ api ๋งŒ๋“ค๊ธฐ โ€‹

axios ์„ค์น˜ โ€‹

shell
npm i axios

expo secure store ์„ค์น˜ โ€‹

https://docs.expo.dev/versions/latest/sdk/securestore/

shell
// ํ† ํฐ ์•”ํ˜ธํ™”ํ•ด์„œ ์ €์žฅ
npx expo install expo-secure-store

๋กœ๊ทธ์ธ ์—ฐ๋™ํ•˜๊ธฐ โ€‹

  • React-Query๋Š” ์„œ๋ฒ„ ์ƒํƒœ๋ฅผ ๊ฐ€์ ธ์˜ค๊ณ  ์บ์‹ฑํ•˜๊ณ  ๋™๊ธฐํ™”ํ•˜๊ฑฐ๋‚˜ ์—…๋ฐ์ดํŠธํ•˜๋Š” ์ž‘์—…์„