-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[서준환] 10장: 리액트 17과 18의 변경 사항 살펴보기 #76
The head ref may contain hidden characters: "10\uC7A5/\uC11C\uC900\uD658"
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,174 @@ | ||
# 10장 리액트 17과 18의 변경 사항 살펴보기 | ||
|
||
이야 react가 npm에 등록된 지 11년이나 됐네요 ㄷㄷ | ||
|
||
## 10.1 리액트 17 버전 살펴보기 | ||
|
||
변경 사항을 최소화 했다는 특징이 있다! | ||
|
||
### 10.1.1 리액트의 점진적인 업그레이드 | ||
|
||
리액트는 정말 친절하게도 기존 버전 api의 지원을 계속해주고 있다. 그래서 기존 버전의 코드를 그대로 사용하면서 새로운 버전의 기능을 사용할 수 있다. | ||
|
||
### 10.1.2 이벤트 위임 방식의 변경 | ||
|
||
리액트에서 이벤트 핸들러를 추가하면 이벤트 하나당 핸들러를 `루트`에 부착한다. | ||
|
||
해당 DOM에 부착하지 않고 루트에 부착하는 이유는 이벤트 위임을 통해 효율적으로 이벤트 핸들러를 관리하기 때문이다. | ||
|
||
여기서 루트란 `document`를 의미한다. | ||
|
||
다만 리액트 17부터는 이벤트 위임이 `document`가 아닌 `root` DOM에 부착된다. | ||
|
||
이러한 이유는 리액트의 점진적인 업그레이드, 여러 라이브러리와 함께 사용했을 때를 고려한 이유다. | ||
|
||
하나의 프로젝트에서 여러 리액트 버전이 존재한다면 이벤트 위임이 `document`에 부착되면서 이벤트가 중복되어 발생할 수 있다. | ||
|
||
이를 통해 각 이벤트를 해당 리액트 컴포넌트 트리 수준으로 `격리`시켜 방지할 수 있다. | ||
|
||
### 10.1.3 import React from 'react'가 더 이상 필요 없다: 새로운 JSX transform | ||
|
||
기존엔 `import React from 'react'`를 해야만 JSX를 사용할 수 있었다. | ||
17부턴 바벨과 협력해 해당 구문 없이도 JSX를 변환할 수 있게 되었다. | ||
|
||
이는 불필요한 import 구문을 삭제해 번들링 크기를 약간 줄일 수 있고, 간결하게 코드를 작성할 수 있다. | ||
|
||
### 10.1.4 그 밖의 주요 변경 사항 | ||
|
||
#### 이벤트 풀링 제거 | ||
|
||
기존엔 `SyntheticEvent`라는 브라우저의 기본 이벤트를 한 번 더 감싼 이벤트 객체를 사용해 관리를 했다. | ||
|
||
그렇기 때문에 새로운 이벤트 객체를 생성할 때마다 이 이벤트를 만들어야 했기에 메모리 사용량이 늘어나는 문제가 있었다. | ||
|
||
더불어 비동기 코드로 이벤트 핸들러에 접근하기 위해선 별도 메모리 공간에 합성 이벤트 객체를 할당해야 했다. | ||
|
||
모던 브라우저에선 성능이 많이 개선되어 해당 이벤트 풀링을 제거했다. | ||
|
||
#### useEffect 클린업 함수의 비동기 실행 | ||
|
||
기존엔 `useEffect`의 클린업 함수가 동기적으로 실행되었다. | ||
|
||
하지만 리액트 17부터는 화면이 완전이 업데이트된 이후에 비동기적으로 실행된다. | ||
|
||
#### 컴포넌트의 undefined 반환에 대한 일관적인 처리 | ||
|
||
리액트 16, 17에서는 컴포넌트가 `undefined`를 반환하면 오류가 발생한다. | ||
이는 의도치 않게 잘못된 반환으로 인한 실수를 방지하기 위해서다. | ||
|
||
그러나 16은 memo, forwardRef 에서 undefined를 반환하면 오류가 발생하지 않았다. | ||
|
||
요것이 수정되었다. | ||
|
||
18은 undefined를 반환해도 오류가 발생하지 않는다. | ||
|
||
> 1도 모르고 있었네요 | ||
|
||
## 10.2 리액트 18 버전 살펴보기 | ||
|
||
### 10.2.1 새로 추가된 훅 살펴보기 | ||
|
||
#### useId | ||
|
||
유니크한 값을 생성하는 훅이다. | ||
|
||
serverSide, clientSide에서 동일한 값을 생성할 수 있다. | ||
|
||
> 알고리즘 봐도 이해가 안 가던데 , , | ||
> help me | ||
|
||
> 참고로 [useId](https://react-spectrum.adobe.com/react-aria/useId.html)는 adobe에서 만든 라이브러리인데 얘네는 provider를 통해 ssr에서 생성한 id를 공유하는 것 같네요! | ||
|
||
#### useTransition | ||
|
||
UI 변경을 가로막지 않고 상태를 업데이트 할 수 있는 훅이다. | ||
|
||
리액트 18의 동시성을 다룰 수 있는 새로운 훅으로 느린 렌더링 과정에서 로딩 화면을 보여주거나 지금 진행 중인 렌더링을 버리고 새로운 렌더링을 시작할 수 있다. | ||
|
||
이는 앱의 성능과 사용자 경험을 향상시키는데 도움이 된다. | ||
|
||
#### useDeferredValue | ||
|
||
리렌더링이 급하지 않은 부분을 지연할 수 있게 도와주는 훅이다. | ||
|
||
이는 useTransition과 비슷하지만 상태를 업데이트 할 수 있지 않은 상태에서 활용이 가능하다. | ||
|
||
#### useSyncExternalStore | ||
|
||
리액트 18에서부터 렌더링을 일시 중지, 뒤로 미루는 등의 최적화가 가능하며 외부 상태간의 동기화 문제가 발생한다. 이를 해결하기 위해 도입된 훅이다. | ||
|
||
> 그렇다면 custom hooks 를 모두 이렇게 만들어 주어야 하는 것인가요? | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "외부 데이터 소스�" 라는 포인트가 중요한 것 같아요! 근데 개인적으로는 테어링 현상을 경험해보지 못해 잘 모르겠네요... |
||
> | ||
> 더불어 custom hook 라이브러리의 경우 특정 react 버전에 따라 내부 구현을 변경하여 제공할 수 있을까요? | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 그러게요 사용자 버전 별로 다른 코드를 서빙한다라 .... 🤔 |
||
|
||
#### useInsertionEffect | ||
|
||
css-in-js 라이브러리를 위한 훅으로 css 의 추가 및 수정은 모든 리액트 컴포넌트에 영향을 미칠 수도 있는 무거운 작업이다. | ||
|
||
useLayoutEffect와 같이 렌더링이 완료되기 전에 동작하게 되는데, useLayoutEffect와의 차이점은 DOM의 변경 작업 이전에 실행된다는 것이다. | ||
|
||
> 따로 사용할 일이 없을 것 같긴 하네요. | ||
|
||
### 10.2.2 react-dom/client | ||
|
||
#### createRoot | ||
|
||
기존은 `ReactDOM.render`를 통해 렌더링을 했다. | ||
|
||
리액트 18부터는 `ReactDOM.createRoot`를 통해 렌더링을 할 수 있다. | ||
|
||
> 제가 알기론 concurrent mode를 사용하기 위해서는 `createRoot`를 사용해야 한다고 알고 있슴니다 . . | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍👍👍 |
||
|
||
#### hydrateRoot | ||
|
||
서버 사이드 렌더링을 할 때 사용하는 메서드다! | ||
|
||
기존에는 `ReactDOM.hydrate`를 사용했는데, 리액트 18부터는 `ReactDOM.hydrateRoot`를 사용해야 한다. | ||
|
||
### 10.2.3 react-dom/server | ||
|
||
#### renderToPipeableStream | ||
|
||
리액트 트리를 파이프 가능한 Node.js 스트림으로 렌더링하는 메서드다. | ||
|
||
요건 조금 더 읽어볼게요 , , | ||
|
||
#### renderToReadableStream | ||
|
||
모던 엣지 런타임 환경에서 사용할 수 있는 메서드다. | ||
|
||
### 10.2.4 자동 배치(automatic batching) | ||
|
||
리액트가 여러 상태 업데이트를 하나의 리렌더링으로 묶어서 성능을 향상시키는 방법 | ||
|
||
리액트 17의 경우에도 자동 배치가 되고 있었지만, 비동기 코드에서는 자동 배치가 되지 않았다. | ||
|
||
리액트 18부터는 비동기 코드에서도 자동 배치가 되어 성능을 향상시킬 수 있다. | ||
|
||
### 10.2.5 더욱 엄격해진 엄격 모드 (엄근진) | ||
|
||
#### 리액트의 엄격 모드 | ||
|
||
잠재적인 버그를 미리 찾아내기 위해 리액트의 엄격 모드를 사용할 수 있다. | ||
|
||
무 적 권 켜놓으십쇼. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ㅋㅋㅋㅋㅋㅋㅋ 별표! |
||
|
||
> 책에서 strict mode를 통해 검출할 수 있는 안 좋은 예시들을 소개해 주고 있는데, 다행스럽게도 본 경험이 없네요,,! | ||
|
||
### 10.2.6 Suspense 기능 강화 | ||
|
||
기존 `Suspense`는 동작하긴 했지만, 컴포넌트가 보이기 전에 `useEffect`가 실행되는 등의 문제가 있었다. | ||
|
||
더불어 서버에서 사용할 수 없었다. 그렇기에 커스텀한 컴포넌트를 만들어 SSR 환경에서도 지원하게끔 만들어야 했다. | ||
|
||
> Suspense에 스로틀링이 추가됐다는데, 정확하게 무슨 의미?,, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Suspense의 Fallback이 노출되있는 상태에서 다시 Susepnse가 실행되는 상황이 있다면 무시한다라는 뜻으로 이해 했어요! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 저도 동규님 말씀 같이 이해했어요!! |
||
|
||
## 마무리 | ||
|
||
리액트 17과 18의 변경 사항을 살펴봤다. | ||
|
||
핵심은 동시성 렌더링이다. 과거엔 렌더링을 시작하면 끝날 때까지 기다려야 했으나, 리액트 18부터는 렌더링을 중단하고 다른 작업을 할 수 있다. | ||
|
||
이를 통해 발생한 문제인 상태 동기화 문제를 해결하기 위해 새로운 훅들이 추가되었다. | ||
|
||
> 라이브러리 만들 때 고려할 점들이 추가됐네요,,! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
저는 알고리즘을 따로 본 건 아닌데요 ...
그냥 트리 위치 기반으로 아이디를 생성하는구나 ... 하고 넘겼습니다 ㅋㅋㅋㅋ