[ 앱 개발자 도전기 : 크로스플랫폼_ReactNative ] RN_RN 2. React Native 기본기 다지기 : 컴포넌트 기반 개발.

0

App_Dev : RN

목록 보기
17/17

[ 앱 개발자 도전기 : 크로스플랫폼_ReactNative ] RN_RN 2. React Native 기본기 다지기 : 컴포넌트 기반 개발.

▽ [ 앱 개발자 도전기 : 크로스플랫폼_ReactNative ] RN_RN 2. React Native 기본기 다지기 : 컴포넌트 기반 개발.

목  차

📲 React Native 기본기 다지기

📍 2. 컴포넌트 기반 개발.

2-1. 컴포넌트 기반 개발

2-2. Props & State 기초

2-3. 단방향 데이터 흐름 & 양방향 데이터 바인딩 패턴

2-4. 스타일링 시스템 (StyleSheet & Flexbox)

📲 React Native 기본기 다지기

📍 2. 컴포넌트 기반 개발.

2-1. 컴포넌트 기반 개발


🗝️ React Native는 컴포넌트(Component) 를 기본 단위로 앱을 구성.

  • 웹의 React와 동일한 철학을 기반으로 가지며, UI와 로직을 '재사용 가능한 단위'로 쪼개서 관리.

함수형 컴포넌트 + JSX 문법.

  • React-Native에서는 "함수형 컴포넌트" 사용이 권장.
import React from 'react';
import { Text, View } from 'react-native';

export default function App() {
  return (
    <View>
      <Text>Hello, React Native!</Text>
    </View>
  );
}
함수형 컴포넌트 예시.
  • View : 웹의 div와 비슷, "레이아웃 컨테이너"의 역할

  • Text : 텍스트 전용 컴포넌트

    • HTML의 p와는 다름
    • RN에서는 반드시 Text 사용해야함.!

JSX란?
  • JSX : JavaScript 안에서 XML/HTML 같은 문법을 작성할 수 있도록 해주는 React 문법.

👉 React Native에서는 DOM이 아니라 네이티브 UI 컴포넌트로 렌더링됨.

🔬 1) 기초적인 설명: 컴포넌트란?

  • React Native의 UI는 " 컴포넌트(Component) " 단위로 구성

    • '컴포넌트'란?
      • 컴포넌트는 UI를 독립적이고 재사용 가능하도록 기능 단위별로 나눠 놓은 단위.
      • 화면의 구성 요소들은 여러가지 컴포넌트들로 이루어짐.
      • RN은 전체 화면을 하나의 덩어리로 만드는 것이 아니라,
        '작은 단위의 컴포넌트들을 조합해서 앱 화면을 구성"
      • 라이프 사이클 API를 통해 컴포넌트가 화면에 나타날 때, 사라질 때, 변할 때 작업 수행 가능

React Native의 UI는 HTML이 아니라 네이티브 플랫폼의 컴포넌트들로 렌더링됩니다.

  • 컴포넌트는 크게 '클래스형 컴포넌트' vs '함수형 컴포넌트'

    • 클래스형 컴포넌트
      • class 키워드 필요.
      • Component로 상속 받아야 함.
      • render() 메소드가 반드시 필요.
      • state, lifeCycle 관련 기능사용 가능.
      • 메모리 자원을 함수형 컴포넌트보다 조금 더 사용.
        import React, {Component} from "react";
        import {View, Text} from 'react-native';
        class App extends Component {
        const name = ‘리액트’;
          render(){
            return(
             <View>
               <Text> {name} </Text>
             </VIew>
        );
        } }
        export default App;
    • 함수형 컴포넌트
      • state, lifeCycle 관련 기능 사용 불가능->Hook 도입으로 해결됨.
      • 메모리 자원을 클래스형 컴포넌트보다 덜 사용한다.
      • 컴포넌트 선언이 편하다.
         import React from "react";
         import {View, Text} from 'react-native';
            const App = () => {
              const name = ‘리액트’;
              return(
                <View>
                  <Text> {name} </Text>
               </VIew>
              }
              export default App;
              ```
  • 함수형 컴포넌트를 이용해 UI와 로직을 독립적이고 재사용 가능하게 관리

  • JSX를 사용해 HTML과 유사한 문법으로 UI를 작성

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

export default function App() {
  return (
    <View>
      <Text>Hello, React Native!</Text>
    </View>
  );
}

🔬 2) 기본 단계: JSX, 함수형 컴포넌트, props 활용.

  • 컴포넌트는 재사용성을 핵심으로 하며, 작은 단위의 UI 블록으로 쪼개는 방식

  • ✅ JSX란?

    • JS안에서 XML/HTML 문법을 사용 가능
    • Babel이 JSX를 React.createElement 호출로 변환.

JSX (JavaScript XML) 는 JavaScript 안에서
XML/HTML 같은 문법을 사용할 수 있게 해주는 문법입니다.
React 컴포넌트에서 UI를 선언적으로 작성할 수 있게 해줍니다.

const title = "Hello";
return <Text>{title}</Text>;

→ 위 코드는 JavaScript 안에서 XML을 사용하는 형태이며, Babel이 이를 다음처럼 변환.

React.createElement(Text, null, title)
  • React Native의 View와 Text는 웹의 'div'와 'p'를 대체.
function Greeting({ name }: { name: string }) {
  return <Text>Hello, {name}!</Text>;
}
  • ✅ 함수형 컴포넌트란?

함수형 컴포넌트(Function Component) 는 컴포넌트를 함수처럼 정의하는 방식.
React 16.8부터는 상태 관리도 useState 등의 Hook을 통해 가능해졌고,
함수형이 클래스형보다 가볍고 읽기 쉽기 때문에 현재는 함수형이 표준.

function Greeting({ name }) {
  return <Text>Hello, {name}</Text>;
}
  • props는 컴포넌트에 전달되는 외부 데이터

  • 컴포넌트는 "순수 함수"처럼 동작 -> 동일한 입력(props)에 대해 동일한 출력(UI)을 제공.

🔬 3) 심화 단계: React Native의 렌더링 흐름과 구조.

  • React Native는 DOM이 없고, JSX가 네이티브 UI 컴포넌트로 매핑하고 렌더링됨.

  • 📌 렌더링 과정 요약:

      1. JSX → React.createElement → Virtual Representation Tree 생성
      1. 내부적으로 Shadow Tree에서 레이아웃 계산
      1. JS 스레드에서 생성된 UI 명령을 Bridge(JS와 네이티브 간 통신)를 통해
        네이티브 UI 컴포넌트 호출
      1. 네이티브 컴포넌트가 실제 화면에 렌더링됨.
  • React 18 이후 RN도 Concurrent Rendering (동시성 렌더링)텍스트 지원

  • 🧠 관련 용어 설명:

용어설명
Shadow TreeReact Native 내부에서 레이아웃 계산용으로 생성되는 트리. Flexbox를 기반으로 함.
BridgeJavaScript ↔ Native 간 데이터를 주고받는 통신 레이어. 성능 이슈의 핵심 포인트 중 하나.
Renderer렌더링 엔진. React Native는 RN 전용 렌더러(RNRenderer)를 사용.
Reconciliation상태(state)나 props가 변경되었을 때, 변경된 부분만 찾아서 UI를 업데이트하는 과정.
FiberReact 16에서 도입된 내부 아키텍처. UI 업데이트를 세분화하고 스케줄링할 수 있게 함.

🔬 4) 연관 복합 개념: 컴포넌트 설계 전략

  • 🏗️ Atomic Design 패턴:

    • UI를 {원자,분자,유기체,템플릿,페이지}의 5단계로 구성하여
      재사용성과 유지보수성을 높이는 디자인 및 개발 방법론.
    • 아토믹 디자인 패턴의 5단계 :
        1. 앱을 원자(Atoms) → 가장 기본적인 UI 요소/
          • ex: 버튼, 입력창 등 단일 요소
        1. 분자(Molecules) → 원자들이 모여 기본적인 기능을 수행하는 그룹
          • ex) 입력 필드 + 버튼 처럼 함께 동작하는 작은 그룹
        1. 유기체(Organisms) → 분자들이 모여 더 복잡한 섹션을 구성
          • ex) 전체 폼이나 리스트 같은 큰 블록
        1. 템플릿(Templates) → 페이지의 레이아웃을 정의/ 유기체들을 배치하여 페이지 구조 정의
          • 페이지의 레이아웃 뼈대
        1. 페이지(Pages)로 계층화 -> 템플릿에 실제 데이터를 채워 넣은 최종 화면.
  • 컴포넌트 분리 기준 :

    • 재사용 가능 여부
    • UI 복잡성
    • 상태 보관 여부
  • 디자인 패턴 : Presentational vs Container Component 패턴

    • UI만 담당(Presentational Component)
      • UI를 표현하고 사용자 인터페이스 관련 로직만 처리.
      • props를 통해 외부에서 데이터를 받고, 화면에 어떻게 보여줄지만 결정
      • 스타일을 포함하고 있으며, 재사용성이 높음
      • 상태를 가지지 않거나, UI 관련 최소한의 상태만 가짐
      • ex) Button, TextInput, Image 등
    • 로직 / 데이터 담당 ( Container Component )
      • 데이터 가져오기, 상태관리, 비즈니스 로직 처리 등 로직을 담당.
      • Presentational 컴포넌트에 데이터를 전달하고, UI 상태를 변경
      • 비즈니스 로직과 관련된 상태를 관리.
      • 스타일을 포함하지 않고, 재사용성이 낮음.
      • 데이터를 가져오고 처리하는 로직을 캡슐화.
      • ex) API 호출, 데이터 변환, 이벤트 처리 등
    • 장점
      • 관심사 분리 : 코드의 가독성과 유지보수성이 향상
      • 재사용성 : Presentational 컴포넌트는 여러 곳에서 재사용 가능
      • 테스트 용이성 : 각 컴포넌트의 역할이 분리되어 테스트하기 용이.
// Presentational
function UserCard({ name }) {
  return <Text>{name}</Text>;
}

// Container
function UserCardContainer() {
  const [name, setName] = useState("안다미로");
  return <UserCard name={name} />;
}

역할을 나누어 컴포넌트를 분리하면 유지보수성이 높아짐.

🔬 5) 실무 적용.

  • Ex 1 ) : 공통 컴포넌트 설계.
// components/Button.tsx
export default function Button({ title, onPress }) {
  return (
    <TouchableOpacity onPress={onPress}>
      <Text>{title}</Text>
    </TouchableOpacity>
  );
}

→ 여러 화면에서 같은 버튼 스타일과 동작을 재사용 가능

  • Ex 2 ) : 컴포넌트 계층 구조 설계.
src/
 └── components/
     ├── atoms/
     │   └── Button.tsx
     ├── molecules/
     │   └── LoginForm.tsx
     └── organisms/
         └── AuthScreen.tsx
  • 디자인 시스템과 일관성 확보
  • 팀원 간 UI 재사용 용이
  • 화면 테스트 및 스토리북 도입 가능

2-2. Props & State 기초


Props ( Properties )

  • 부모 -> 자식 컴포넌트로 전달되는 '읽기 전용' 데이터.

  • 불변(immutable) 속성 ==>> "수정 불가"!!

function Greeting({ name }: { name: string }) {
  return <Text>Hello, {name}!</Text>;
}

export default function App() {
  return <Greeting name="안다미로" />;
}

설명 -> App에서 Greeting으로 'name'이라는 prop 전달.

State

  • 컴포넌트 내부에서 관리하는 동적 데이터

  • useState 'Hook'으로 선언.!

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

export default function Counter() {
  const [count, setCount] = useState(0);

  return (
    <View>
      <Text>현재 카운트: {count}</Text>
      <Button title="증가" onPress={() => setCount(count + 1)} />
    </View>
  );
}

설명 -> 버튼을 클릭하면 count 값이 업데이트되고, 화면이 리렌더링.

🔬 1) 기초적인 설명: Props와 State란?

  • React Natvie에서 UI를 동적으로 구성하기 위해서는 컴포넌트에 '데이터 전달과 상태 관리'가 필요.
    • 그 핵심 도구가 Props와 State.
  • ✅ Props (Properties : 속성)

    Props는 부모 컴포넌트가 자식 컴포넌트에 전달하는 읽기 전용 데이터.
    UI를 구성하는 데 필요한 외부 데이터를 전달함.
    마치 HTML의 태그 속성과 비슷한 역할을 하며, 컴포넌트를 재사용 가능하게 만들어줌.

function Greeting({ name }) {
  return <Text>Hello, {name}</Text>;
}

<Greeting name="안다미로" />
  • 여기서 name="안다미로" 는 부모가 자식에게 전달한 props
  • 컴포넌트는 props를 이용해서, UI를 다르게 렌더링할 수 있음.
  • props는 직접 수정할 수 없고 불변(immutable)
  • ✅ State (상태).

    State는 컴포넌트 내부에서 사용하는 변할 수 있는 데이터(상태)입니다.
    상태가 변경되면 해당 컴포넌트는
    자동으로 리렌더링**되어 변경사항이 UI에 반영

const [count, setCount] = useState(0);
  • count: 현재 상태값
  • setCount : 상태를 변경하는 함수
  • useState : React Native에서 상태를 사용할 수 있게 해주는 Hook,
    함수형 컴포넌트에서 상태를 사용할 수 있게 함.

🔬 2) 기본 단계: Props/State의 작동 원리와 관계.

  • 💡 Props와 State의 차이점.
항목PropsState
정의외부에서 전달받는 데이터내부에서 선언한 상태값
변경 가능 여부불변 (읽기 전용)변경 가능 (setState 등)
책임 주체부모 컴포넌트자신(또는 Context 등)
용도컴포넌트 구성/데이터 전달UI의 동적 변경
  • Props는 불변성 유지, State는 리렌더링 트리거

  • State 업데이트 시 RN의 Shadow Tree와 비교 후 필요한 부분만 업데이트.

  • useState는 '비동기적'으로 작동(즉시 반영되지 않을 수 있음)

  • 🔁 State가 변경되면 무슨 일이 일어나는가??

      1. setState() 또는 setCount() 호출
      1. 컴포넌트의 상태가 변경됨
      1. React Native는 Shadow Tree를 재계산
      1. 변경된 레이아웃 정보가 Bridge를 통해 네이티브 코드에 전달
      1. 실제 화면의 Native View가 업데이트.

🔬 3) 심화 단계: 상태 변화의 내부 흐름

  • 🧠 렌더링 과정 in React Native

    • React Native는 DOM이나 Vritual DOM이 없음.

    • 대신, 상태(State) 변경 시 다음 흐름으로 작동.

       useState로 상태 변경 →
       React Fiber에서 Shadow Tree 재구성 →
      Yoga 엔진으로 레이아웃 계산 →
      Bridge로 네이티브에 전달 →
      실제 UI(Native View) 렌더링
      
  • ❗ 비동기 상태 처리

setCount(count + 1);
console.log(count); // 여전히 이전 값 출력됨
  • 상태는 '즉시 업데이트되지 않음'
  • 렌더링 사이클에서 다음 렌더링에 반영.
  • ✅ 함수형 업데이트 방식.

    setCount(prev => prev + 1);
    
    • 비동기 문제를 회피하고 '정확한 상태 누적'을 가능하게 함.

🔬 4) 연관 복합 개념. : 상태 관리 전략들

  • ✅ 데이터 흐름 구조 (단방향 흐름)
    • React Native의 데이터는 항상 부모->자식 방향으로 흐름
    • 데이터 추적이 용이하고 예측 가능함.
  • ✅ Props Drilling → 해결책
// 여러 단계 하위 컴포넌트에 props 넘기는 문제 발생
  • 해결 방법.
    • Context API : 경로 없이 상태전달
    • 상태 관리 라이브러리 : Redux, Zustand 등
  • ✅ 상태 종류 분류.
상태 종류설명대표 도구
Local State컴포넌트 내부 상태useState, useReducer
Global State여러 컴포넌트에서 공유하는 상태Context, Redux, Zustand
Server StateAPI로부터 가져온 외부 데이터React Query, SWR
Navigation State현재 화면, 파라미터 등React Navigation

🔬 5) 실무 적용 예시.

  • 예시 1: 로그인 입력 처리.
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
  • TextInput 컴포넌트와 바인딩
  • 입력값에 따라 상태가 실시간 반영됨.
  • 예시 2: 검색창 디바운싱 처리
useEffect(() => {
  const timeout = setTimeout(() => {
    search(text);
  }, 300);
  return () => clearTimeout(timeout);
}, [text]);
  • 입력 도중 API 요청 방지
  • 입력 멈춘 후 일정 시간 후에 요청 -> 성능 최적화.

2-3. 단방향 데이터 흐름 & 양방향 데이터 바인딩 패턴 & 이벤트 처리 및 사용자 상호작용


단방향 데이터 흐름 (React 기본 철학)

  • 데이터는 "위 -> 아래 ( 부모 -> 자식 )" 방향으로 전달됨.

  • ex)

function Child({ value }: { value: number }) {
  return <Text>값: {value}</Text>;
}

export default function Parent() {
  return <Child value={10} />;
}

설명 -> Parent에서 Child로 'value'이라는 prop 전달.

양방향 데이터 바인딩 (입력값 반영)

  • React-Native 자체는 "단방향 데이터 흐름"을 따르지만,

  • TextInput + useState 조합으로 " 양방향 '처럼' " 구현 가능.

import React, { useState } from 'react';
import { View, TextInput, Text } from 'react-native';

export default function InputExample() {
  const [text, setText] = useState('');

  return (
    <View>
      <TextInput
        value={text}
        onChangeText={setText}
        placeholder="텍스트를 입력하세요"
        style={{ borderWidth: 1, padding: 8 }}
      />
      <Text>입력값: {text}</Text>
    </View>
  );
}
  • 사용자가 '입력'을 하면 'onChangeText' -> 'setText' 호출

  • state 변경 -> UI 자동 업데이트.

  • 즉, "단방향 흐름을 기반으로 한 양방향 구현"

🔬 1) 기초 설명: 이벤트 처리란?

  • React Native는 "단방향 데이터 흐름"을 기본 원칙으로 가짐.

  • 부모 -> 자식 방향으로만 데이터가 흐름.!

  • React Native에서는 사용자의 터치 이벤트를 처리하기 위해
    전용 컴포넌트와 콜백 함수를 사용합니다.

    • 웹의 웹의 onClick, onChange와 유사하지만, Native 터치 이벤트 시스템 기반!

🔬 2) 기본 단계: 버튼 클릭 처리

import { Button, Alert } from 'react-native';

<Button title="눌러보세요" onPress={() => Alert.alert("눌림")} />
  • onPress : 버튼을 눌렀을 때 실행될 콜백
  • Alert.alert : RN에서 기본 제공하는 경고창 함수.
const handlePress = () => {
  console.log("사용자가 버튼을 눌렀습니다");
};

🔬 3) 심화 단계: 다양한 상호작용 요소.

컴포넌트설명
TouchableOpacity터치 시 투명도 변화
TouchableHighlight터치 시 배경 강조
Pressable다양한 상태별 스타일링 지원
Gesture Handler고급 제스처 처리 (swipe 등)
<Pressable onPressIn={...} onLongPress={...} onPressOut={...} />

🔬 4) 연관 개념: 제스처, 상태 제어, 키보드 처리

  • ✅ KeyboardAvoidingView
    • 입력창이 있을 때 키보드에 의해 가려지지 않도록 레이아웃 조정
<KeyboardAvoidingView behavior="padding">
  <TextInput />
</KeyboardAvoidingView>
  • ✅ Focus 제어, ScrollView 연동.

    • useRef와 ref.current.focus()로 TextInput 포커스 제어
    • 키보드 닫기 : keyboard.dismiss()

🔬 5) 실무 적용 예시.

  • 예시 1: 로그인 폼 구성.
<TextInput value={email} onChangeText={setEmail} keyboardType="email-address" />
<TextInput value={password} onChangeText={setPassword} secureTextEntry />
  • 키보드 타입 설정
  • secureTextEntry 로 비밀번호 입력
  • 예시 2: 커스텀 버튼 + 피드백.
<TouchableOpacity onPress={handlePress} activeOpacity={0.6}>
  <Text>로그인</Text>
</TouchableOpacity>

2-4. 스타일링 시스템 (StyleSheet & Flexbox)


🔬 1) 기초 설명: 스타일 적용 방식

  • React Native는 CSS가 아니라 JS 기반 스타일 시스템을 사용.!
import { StyleSheet } from 'react-native';

const styles = StyleSheet.create({
  container: {
    backgroundColor: 'white',
    padding: 16,
  },
});
  • StyleSheet.create()는 '정적 스타일'을 정의.
  • "런타임에서 스타일 최적화 가능"

🔬 2) 기본 단계: 주요 스타일 속성

속성설명
flex, flexDirection레이아웃 구성
padding, margin여백 조정
alignItems, justifyContent정렬 방식
color, fontSize텍스트 스타일링
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }} />

🔬 3) 심화 단계: Flexbox 레이아웃

  • React Native에서는 FlexBox가 '기본 레이아웃 시스템'
  • row/column 방향 설정이 핵심.
<View style={{ flexDirection: 'row', justifyContent: 'space-between' }} />
속성설명
flexDirectionrow, column
justifyContentflex-start, center, space-between
alignItemsflex-start, center, stretch

🔬 4) 연관 개념: 반응형, 다크모드, 커스텀 테마

  • ✅ 반응형 디자인

    • Dimensions.get('window'), useWindowDimensions()

    • 퍼센트 단위 또는 Flex 기반 구성

  • ✅ 다크모드 대응

const colorScheme = useColorScheme();
const isDark = colorScheme === 'dark';
  • ✅ 테마 시스템.

    • ThemeProvider, Context API로 글로벌 스타일 관리

🔬 5) 실무 적용 예시.

  • 예시 1 : 전체 화면 중앙 정렬
const styles = StyleSheet.create({
  center: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
});
  • 예시 2 : 버튼 커스터마이징
<TouchableOpacity style={styles.button}>
  <Text style={styles.buttonText}>로그인</Text>
</TouchableOpacity>

const styles = StyleSheet.create({
  button: {
    backgroundColor: '#2196F3',
    paddingVertical: 12,
    paddingHorizontal: 24,
    borderRadius: 8,
  },
  buttonText: {
    color: 'white',
    fontWeight: 'bold',
  },
});

0개의 댓글