Binding
Binding = View + Model
- 리엑트는 단방향 바인딩이다
- Model이 변경되면 View가 자동으로 변경된다
- 컴포넌트에서 부모에서 자식으로 값이 아래로만 전달된다
- View에서 Model을 변경하고 싶다면 Controller를 사용하면 된다!
- 장점:
- 명확한 Model과 View의 책임 분리
- 일관된 데이터 로직
- 잘쓰면 성능 저하없는 DOM Rerender가 가능하다
- 단점:
- 사용자의 HTML에 대한 입력 및 이벤트 발생 시 데이터 감지 코드를 매번 작성해야한다 =
setState
- 사용자의 HTML에 대한 입력 및 이벤트 발생 시 데이터 감지 코드를 매번 작성해야한다 =
- Model이 변경되면 View가 자동으로 변경된다
- 예시
function CustomInput({ value, onChange }) {
// 1. value 상태를 통해 input 을 변경하기만 합니다.
return <input type='number' value={value} onChange={onChange} />
}
- 양방향 바인딩?
- 자식이 부모에게 값을 올려주는것이 가능하면 양방향 바인딩이다
- 장점:
- 코드가 단순해진다
- 단점:
- 역방향 변화 발생 시 DOM 객체 전체 렌더링 (혹은 데이터 변환)이 필요하며 성능이 저하된다
- 주로 Vue나 Angular에서 쓰인다
- 양방향 바인딩의 예시:
function CustomInput({ value }) {
// 1. value 상태를 통해 input 을 변경하기도 하지만
// 2. input 이 변경되면 value 상태도 변경되는것입니다.
return <input type='number' value={value} />
}
VDOM & Lifecycle of React
리엑트는 이전 버전과 바뀐 VDOM을 비교하여 바뀐 부분만 Repaint를 진행한다
- Reconsilation (재조정, 비교) 가 필요하여 메모리를 두배로 쓴다!
- Angular에서는 Incremental DOM을 사용하여 메모리에 효율적이다
- LifeCycle
- Render → Reconciliate → Commit → Paint 순으로 LifeCycle이 생성된다
- 컴포넌트 랜더링 - Render: JSX → JS → JSON (V-DOM)을 반환한다
- 변경사항 비교 - Reconciliate: 이전 버전과 이후 버전을 비교한다
- Commit Phase - 앞선 재조정된 VDOM들을 모아 실제 DOM을 생성한다
- 여기서 이전에 확인한 부분들을 변경한다
useLayoutEffect()를 호출한다- 이건 React가 아닌, Web Browser가 한다!
- Paint 이전에 동기적으로 수행된다
- 웹 페이지가 보이기까지의 시간을 지연시킨다
- (Re)Paint: Web Browser Rendering - 최종적으로 HTML View를 그려준다
useEffect()를 호출한다- Paint 직후에 비동기적으로 수행된다
- 이것 또한 Web Browser가 한다
- React는 언제 Rerende가 되나?
- 부모가 Rerender 됬을때, 하위 자식들도 전부 Rerender가 된다
- Component가 가진 상태가 바뀌었을떄
- Component가 Props로 받아온 state가 바뀌었을때
- Commit까지는 Pure하다고 한다
- Pure: no side effect exist
useLayoutEffect()와useEffect는 Side effect hook이라고 부른다
- React Render Liftcycle 후 처리
useLayoutEffect(): 페이지 레이아웃을 보기 전에 동기적으로 실행한다- 목적: Measuring layout before the browser repaints the screen
- paint: Viewport가 크거나 HTML 요소 위치 등 을 알아야할 때
- 페인트 전에 연산이 일어난다
- 동기적으로 실행된다
- 로직이 간단한 경우, 사용자가 페이지 일부의 깜빡임 (Loading)을 겪지 않아도 된다
- 하지만 로직이 복잡한 경우, 전체 페이지 Layout을 보는데까지 딜레이가 발생할 수 있다
- await 호출이 안되기에 API호출은
useEffect()를 사용하는게 좋다
- 목적: Measuring layout before the browser repaints the screen
useEffect(): 페이지 레이아웃을 본 후 비동기적으로 실행한다- 목적: API 연결, Non-React 위젯 구동, Prop 변경에 따른 State 재계산
순서: useState → useLayoutEffect → useEffect
