진도
브라우저에서 JS engine을 떼어내어 JS code로 구현된 View
class를 Native framework의View
class로 호출하여 연결
DHTML(동적 HTML) 방식은 객체 지향 언어의 상속 관계로 설계한 "DOM(문서 객체 모델)
타입 자바스크립트 객체"를 생성하여 동작
<div>
,<h1>
React에는 독특하게 Physical(물리) DOM 구조와 Virtual(가상) DOM 구조를 사용
react-dom(*DOM Renderer)
이라는 renderer 패키지를 사용하여 physical DOM 구조로 랜더링react-native(*Native Renderer)
라는 renderer 패키지를 사용하여 랜더링Android framework
나 iOS UIKit framework
의 화면 UI 객체로 바꿔주는 역할 수행RN app을 설치 후 실행하면 Thread 동작 어떻게 될까?
UI Thread
와 App.tsx와 같은 JS code를 실행하는 JS engine Thread
2개가 동시에 동작react-native 전용 패키지에는 항상 JS Thread에서 동작하는 쪽과 UI Thread에서 동작하는 쪽이 따로 있다. 때문에 두 패키지를 모두 설치해야 정상 동작
react-native framwork에서 가상 DOM 객체 생성
const textElement = React.createElement(Text, null, 'Hello World')
react-native framework에서 가상 DOM 객체를 물리 DOM 객체로 변환 하는 방법
import ReactDOM from 'react-dom'
const pElement = React.createElement('p', null, 'Hello World')
ReactDOM.render(pElement, document.body)
react-native renderer가 가상 DOM 객체를 native로 넘기는 방법
export default function App() {
const textElement = React.createElement(Text, null, 'Hello World')
return textElement
}
react-native-cli는 네이티브 모듈에서 동작하는 js engine이 가상 DOM 객체를 넘겨주는 App의 존재를 알 수 있도록 (1) index.js 파일 생성, (2) 자바 파일 생성 필요
// (1) index.js
import {AppRegistry} from 'react-native'
import App from './App'
import {name as appName} from './app.json'
AppRegistry.registerComponent(appName, () => App)
// (2) android/app/src/main/java/com/win/MainApplication.java
...
@Override
protected String getJSMainModuleName() {
return "index"
};
...
npm i
: package.json 파일에 명시된 패키지를 node_modules 디렉터리에 설치. 설치한 패키지는 android 나 ios 디렉터리의 네이티브 모듈에서 동작하는 파일을 가짐[Android commands]
npm run android
: android app build commandnpm start
: 메트로 서버 실행 명령 (메트로 서버? 설치된 앱이 처음 구동될 때 앱이 수신해야 할 ES5 js code로 컴파일된 ts code 번들을 제공)./gradlew installDebug
: android build.gradle(app 수준) 내용을 참조하여 빌드 (실행 파일 생성)[iOS commands]
npm run ios
: Xcode의 빌드 명령 실행, 빌드한 앱을 시뮬레이터에 설치하고 실행npm start
: 메트로 서버에서 ts code를 컴파일한 js code 번들을 내려받아 실행npx pod-install
: ios directory의 Podfile 실행 명령. 필요한 패키지를 내려받아 로컬 컴퓨터에 설치npx react-native init
: 프로젝트를 생성하면서 npx pod-install
명령도 자동으로 실행[프로젝트 초기화 commands]
./gradlew clean
: ./gradlew installDebug
명령으로 생성된 임시 파일을 삭제. 원격지 저장소에서 내려받은 패키지도 함께 삭제rm -r force .gradle (window)
rm -rf .gradle (mac)
: 빌드한 앱 삭제xcodebuild clean
: Xcode가 생성한 임시 파일 삭제pod deintegrate
: npx pod-install 명령으로 내려받은 패키지 삭제JSX : JavaScript + XML
XML에 JS를 결합할 용도로 만든 구문
.tsx
import React from 'react'
필요Babel
구조를 통해 JS를 확장하여 React.createElement 코드를 더욱 간결하게 사용 가능
Babel
이 플러그인 구조로 동작[참고]
- transpiler : source code -> source code
- compiler : source code -> binary code
[출처 : https://greendreamtrre.tistory.com/718]
Component는 여러개의 property와 하나 이상의 자식 Component를 가질 수 있다.
XML에 js code를 삽입 가능
const hello = 'Hello World'
<Text>{hello}</Text>
JSX syntax의 js code는 반드시 return 키워드 없이 값을 반환 -> ESNext js에서의 '표현식'
JSX 밖에서 if문
const isLoading = true
if (isLoading) {
return (
<SafeAreaView>
...
</SafeAreaView>
)
}
return (
<SafeAreaView>
...
</SafeAreaView>
)
단축 평가 조건문 (short circuit evaluation)
JSX parser는 undefined 혹은 null인 결과를 무시한다.
const isLoading = true
return (
<SafeAreaView>
// isLoading ? <Text>...</Text> : undefined
{isLoading && <Text>...</Text>}
// !isLoading ? <Text>...</Text> : undefined
{!isLoading && <Text>...</Text>}
</SafeAreaView>
)
변수에 JSX문을 담기
const isLoading = true
const children = isLoading ? (
<Text>...</Text>
) : (
<Text>Hello JSX world</Text>
)
return <SafeAreaView>{children}</SafeAreaView>
배열에 여러개의 JSX문을 담기
*부모없이 여러 개의 XML요소를 만들 수 없다.
const children = [
<Text>...</Text>,
<Text>...</Text>,
<Text>...</Text>
]
// 부모 없이 홀로 작성 불가
// return children
// return {children}
// 반드시 부모 컴포넌트의 자식 컴포넌트 형태로 작성
return <SafeAreaView>{children}</SafeAreaView>
데이터 배열을 컴포넌트 배열로 만들기
const children = [1, 2, 3].map((i) => <Text>Hello {i}</Text>)
조금씩 다른 100개의 컴포넌트 배열 만들기
const children = new Array(100) // undefined로 채워진 배열 생성
.fill(null) // undefined로는 map 사용 불가하여 null로 배열 채우기
.map((notUsed, index) => <Text>Hello {index}</Text>)
React framework는 컴포넌트라는 기법으로 가상 DOM 객체를 만들고 가상 DOM 객체에 어떤 변화가 감지되면 해당 변화만 화면에 재렌더링하여 전체 렌더링 속도를 빠르게 하는 목적을 가진 framework이다.
React Hooks의 탄생 배경이 된 클래스 컴포넌트의 문제점
용도 | hooks | 요약 |
---|---|---|
컴포넌트 데이터 관리 | useMemo | |
useCallback | ||
useState | ||
useReducer | ||
컴포넌트 생명주기 대응 | useEffect | 비동기로 실행(콜백 함수의 종료를 기다리지 않음) |
useLayoutEffect | 동기로 실행(콜백 함수의 종료를 기다림) | |
컴포넌트 간의 정보 공유 | useContext | |
컴포넌트 메서드 호출 | useRef | |
컴포넌트 메서드 호출 | useImperativeHandle |
기본 Hooks
app 상태 관리 라이브러리
1. State :
objects, arrays, primitives, references의 그래프 형태로 어플리케이션을 구성. 이것들은 spreadsheet의 data cells이 될 것
2. Derivations :
어플리케이션으로부터 자동으로 계산되는 모든 값을 뜻함. 이 값들은 간단한 값에서부터 복잡한 시각적 html 표현까지 다양한 값이 될 수 있다. spreadsheet의 chart 개념과 비슷
3. Reactions :
Derivations와 유사한 개념. 가장 큰 차이점은 값을 생성하지 않는 함수라는 것이다. 대신 자동으로 특정 작업들을 수행시켜주고, 이는 대체로 I/O와 연관된 작업들이다. reaction은 적당한 때에 자동으로 DOM을 업데이트하게 해주고 네트워크 요청을 하도록 해준다.
4. Actions :
state를 변경하는 모든 것. 이 action들은 모두 동기적으로 처리된다.
[출처 : https://mobx.js.org/getting-started]
Context의 주된 용도는 다양한 레벨에 nesting된 많은 컴포넌트에게 데이터를 전달하는 것
Context를 사용하면 컴포넌트를 재사용하기 어려워지므로 꼭 필요할 때만 사용
[출처 : https://jeffgukang.github.io/react-native-tutorial/docs/router-tutorial/react-navigation-stack/react-navigation-stack-kr.html]
https://reactnavigation.org/docs/getting-started/
references:
[책] Do it! 리액트 네이티브 앱 프로그래밍, 전예홍 저, 이지스퍼블리싱
[문서] https://reactnative.dev/docs/intro-react