-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
53d46a3
commit 1f71296
Showing
1 changed file
with
170 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,170 @@ | ||
# 10장 리액트 17과 18의 변경 사항 살펴보기 | ||
|
||
#스터디-리액트딥다이브 | ||
현재 리액트로 운영중인 웹 애플리케이션은 16버전을 가장 많이 사용하고 있다. 함수형 컴포넌트와 훅으로 인해 고착화 된 듯 보이지만 최신 버전에 대해서 알아야 한다. | ||
|
||
## 10.1 리액트 17 버전 살펴보기 | ||
|
||
16버전과 Breaking Changes를 최소화 했다는 것을 가장 큰 특징으로 꼽는다. | ||
|
||
### 10.1.1 리액트의 점진적인 업그레이드 | ||
|
||
리액트는 시멘틱 버저닝 방법으로 업데이트를 진행하고 있다. 전체 애플리케이션이 17버전이지만, 일부 트리와 컴포넌트에 대해서만 18버전을 선택하는 점진적인 버전 업이 가능하다. | ||
리액트 17 애플리케이션을 16을 내부적으로 Lazy하게 불러온다. 다만, 이것은 임시방편이고 한꺼번에 업데이트 하는것이 복잡성 감소 측면에 좋다. | ||
|
||
### 10.1.2 이벤트 위임 방식의 변경 | ||
|
||
그냥 버튼의 이벤트 핸들러는 DOM을 직접 참조해서 가져오고 onclick 함수를 직접 추가한다. 하지만 리액트 버튼의 이벤트 핸들러는 아무런 동작도 하지 않는다. | ||
이벤트 타입당 하나의 핸들러를 루트에 부착한다. (이벤트 위임) | ||
|
||
- **캡처:** 이벤트 핸들러가 최상단 -> 실제 이벤트 타깃 요소 까지 내려가는 것을 의미 | ||
- **타깃:** 이벤트 핸들러가 노드에 도달하는 단계 | ||
- **버블링:** 이벤트가 발생한 요소에서부터 시작해 최상위 요소까지 다시 올라간다. | ||
|
||
**이벤트 위임**이란 이런 원리를 이용해 상위 컴포넌트에만 이벤트를 부착하는 것을 말한다. 결국, 자식 요소와 상관없이 상위 컴포넌트에서만 관리하면 되기에 효율적이다. | ||
리액트 17부터는 이벤트 위임이 document가 아닌 컴포넌트 최상단 트리인 루트요소로 변경 되었다. | ||
|
||
- 점진적 업그레이드 지원 및 다른 바닐라 자바스크립트 코드 또는 JQuery 등이 혼재 되어 있는 경우 혼란을 방지하기 위해서다. | ||
|
||
### 10.1.3 import React from ‘react’가 더 이상 필요 없다: 새로운 JSX transform | ||
|
||
16 버전에는 `import React from 'react'` 코드가 없다면 에러가 발생했다. 17 버전 부터는 “바벨과 협력하여 이런 import 구문 없이도 jsx를 변환할 수 있다.” | ||
|
||
```sh | ||
npx react-codemod update-react-imports | ||
``` | ||
|
||
명령어를 통해 기존에 추가된 구문들을 모두 삭제할 수 있다. eslint를 활용하는 방법도 있다. | ||
|
||
### 10.1.4 그 밖의 주요 변경 사항 | ||
|
||
#### 이벤트 풀링 제거 | ||
|
||
SyntheticEvent 풀을 만들어서 이벤트가 발생할 때마다 가져오는 것을 의미한다. | ||
|
||
- 비동기 코드로 이벤트 핸들러에 접근하기 위해서 별도 메모리 공간에 합성 이벤트 객체를 할당 | ||
- 모던 브러우저에서는 이와 같은 방식이 성능 향상에 크게 도움이 되지 않는다. | ||
2가지 잉로 이벤트 풀링 개념이 삭제 되었다. | ||
|
||
#### useEffect 클린업 함수의 비동기 실행 | ||
|
||
16버전 까지는 클린업 함수가 동기적으로 처리 되었다. 17버전 부터는 비동기적으로 실행된다. 즉, 화면 업데이트가 완전히 끝난 이후 실행된다. | ||
|
||
#### 컴포넌트의 undefined 반환에 대한 일관적인 처리 | ||
|
||
17 부터 undefined가 반환되는 경우 에러가 정상적으로 발생. 18부터는 undefiend를 반환해도 에러가 발생하지 않는다. | ||
|
||
### 10.1.5 정리 | ||
|
||
16버전을 사용하고 있다면 17버전으로 업데이트하는 것을 권장한다. | ||
|
||
## 10.2 리액트 18 버전 살펴보기 | ||
|
||
리액트 18의 가장 큰 변경점은 동시성 지원이다. | ||
|
||
### 10.2.1 새로 추가된 훅 살펴보기 | ||
|
||
#### useId | ||
|
||
컴포넌트별로 유니크한 값을 생성하는 훅이다. | ||
|
||
#### useTransition | ||
|
||
UI 변경을 가로막지 않고 상태를 업데이트할 수 있는 리액트 훅이다. 무거운 렌더링 작업을 조금 미룰 수 있다. 마치 async await처럼 동시성을 다룰 수 있는 훅이다. | ||
|
||
#### useDeferredValue | ||
|
||
컴포넌트 트리에서 리렌더링이 급하지 않은 부분을 지연할 수 있게 도와주는 훅이다. 디바운스와 비슷하지만, 고정된 지연 시간 없이 렌더링 완료된 이후에 실행한다. | ||
useTransition과의 차이는 state를 업데이트를 하는 함수를 감싸서 사용하는 반면, useDeferredValue는 state 값 자체만을 감싸서 사용하는 것을 볼 수 있다. | ||
|
||
- 직접 변경 가능 = useTransition | ||
- 불가능 = useDeferredValue | ||
|
||
#### useSyncExternalStore | ||
|
||
리액트 17의 useSubscription이 리액트 18 대체된 훅이다. useTransition이나 useDeferredValue 같은 훅으로 인해 동시성 이슈가 발생할 수 있다. 내부적으로는 처리 되어있지만, 값을 사용하는 외부에서는 값이 찢어지는 테어링 현상이 일어 날 수 있다. 이러한 문제를 해결하기 위한 훅이다. | ||
이 훅의 외부 스토어 데이터 변경 또한 리렌더링을 발생시킬 수 있다. | ||
|
||
#### useInsertionEffect | ||
|
||
CSS-in-js 라이브러리를 위한 훅이다. DOM이 실제로 변경되기 전에 동기적으로 실행된다. 브라우저가 레이아웃을 계산하기 전에 실행될 수 있게끔 해서 좀 더 자연스러운 스타일 삽입이 가능해진다. | ||
|
||
### 10.2.2 react-dom/client | ||
|
||
클라이언트에서 리액트 트리를 만들 때 사용되는 API가 변경됐다. | ||
|
||
#### createRoot | ||
|
||
기존의 react-dom에 있던 render 메서드를 대체할 새로운 메서드이다. | ||
|
||
#### hydrateRoot | ||
|
||
서버 사이드 렌더링 애플리케이션에서 하이드레이션을 하기 위한 새로운 메서드이다. | ||
|
||
### 10.2.3 react-dom/server | ||
|
||
#### renderToPipeableStream | ||
|
||
리액트 컴포넌트를 HTML로 렌더링하는 메서드이다. 클라이언트에서는 중간에 script를 삽입하는 등의 작업을 할 수 있다. | ||
|
||
#### rederToReadableStream | ||
|
||
웹 스트림을 기반으로 작동한다는 차이가 있다. | ||
|
||
### 10.2.4 자동 배치 | ||
|
||
여러 상태 업데이트를 하나로 묶어서 성능을 향상시키는 방법을 의미한다. Priomise를 사용해 고의로 실행을 지연시키는 sleep 함수를 호출하지 않으면 버전과 상관없이 동일하게 한 번만 렌더링 된다. | ||
이런 자동 배치를 하고싶지 않거나, 이런 방식이 기존 코드에 영향을 미칠 것 으로 예상된다면 `flushSync`를 사용하자. | ||
|
||
### 10.2.5 더욱 엄격해진 엄격 모드 | ||
|
||
#### 리액트의 엄격 모드 | ||
|
||
리액트에서 제공하는 컴포넌트 중 하나로, 잠재적인 버그를 찾는 데 도움이 되는 컴포넌트이다. | ||
|
||
- 더 이상 안전하지 않은 특정 생명주기를 사용하는 컴포넌트에 대한 경고 | ||
- 문자열 ref 사용 금지 | ||
- 여러 컴포넌트에 걸쳐 사용될 수 있으므로 충돌의 여지가 있다. | ||
- 어떤 ref에서 참조되고 있는지 파악하기 어렵다. | ||
- 컴포넌트 ref의 값을 추적해야 하기에 성능이슈가 있다. | ||
- findDOMNode에 대한 경고 출력 | ||
- 구 Context API 사용 시 발생하는 경고 | ||
- 예상치 못한 부작용(Side-Effect) 검사 | ||
|
||
#### 리액트 18에서 추가된 엄격 모드 | ||
|
||
컴포넌트 트리에서 해제 되더라도 내부 상태값은 유지 되는 기능 추가를 위한 엄격모드를 추가 했다. | ||
|
||
```생각 & 의견 | ||
https://ko.vuejs.org/guide/built-ins/keep-alive | ||
Vue에서는 Keep-Alive라고 별도 컴포넌트로 제공해주고 있어요! | ||
``` | ||
|
||
### 10.2.6 Suspense 기능 강화 | ||
|
||
기존의 문제점들이 있었다. | ||
|
||
- 컴포넌트가 보이기 전에 useEffect가 실행 되는 문제가 존재했다. | ||
- 서버에서 사용할 수 없다. | ||
위의 문제들을 해결했다. | ||
|
||
```생각 & 의견 | ||
Next.js(13, react 18)에서 Suspense 사용할 때 그냥 되나요?? 저는 안되는 것 던데... | ||
``` | ||
|
||
### 10.2.7 인터넷 익스플로러 지원 중단에 따른 추가 폴리필 필요 | ||
|
||
- Promise | ||
- Symbol | ||
- Object.assign | ||
이 3가지 기능을 지원한다라는 가정하에 리액트는 배포된다. 지원안하는 경우 폴리필이 필요하다. | ||
|
||
### 10.2.8 그 밖에 알아두면 좋은 사항 | ||
|
||
- undefined 반환은 null 반환과 동일하게 처리된다. | ||
- <Suspense fallback={undefeined} /> 도 null과 동일하게 처리된다. | ||
- renderToNodeStream이 지원 중단되었다. renderToPieableStream을 사용하는 것이 권장된다. | ||
|
||
### 10.2.9 정리 | ||
|
||
리액트 18버전의 핵심은 동시성 렌더링이다. 많은 기능이 추가 되었지만, 핵심은 점진적으로 기능을 채택할 수 있게 하는 것이다. 앞으로 개발할 애플리케이션에서 동시성 모드를 염두에 두고 있다면 사용하고자 하는 라이브러리가 이를 완벽하게 지원하는지 검토가 필요하다. |