From 70eb195eee8eb12a211db762ccd0751558f19007 Mon Sep 17 00:00:00 2001 From: Junhwan Date: Thu, 22 Feb 2024 18:50:22 +0900 Subject: [PATCH] =?UTF-8?q?docs:=2010=EC=9E=A5=20(#76)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../\354\204\234\354\244\200\355\231\230.md" | 174 ++++++++++++++++++ 1 file changed, 174 insertions(+) create mode 100644 "10\354\236\245/\354\204\234\354\244\200\355\231\230.md" diff --git "a/10\354\236\245/\354\204\234\354\244\200\355\231\230.md" "b/10\354\236\245/\354\204\234\354\244\200\355\231\230.md" new file mode 100644 index 0000000..1e6033f --- /dev/null +++ "b/10\354\236\245/\354\204\234\354\244\200\355\231\230.md" @@ -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 를 모두 이렇게 만들어 주어야 하는 것인가요? +> +> 더불어 custom hook 라이브러리의 경우 특정 react 버전에 따라 내부 구현을 변경하여 제공할 수 있을까요? + +#### useInsertionEffect + +css-in-js 라이브러리를 위한 훅으로 css 의 추가 및 수정은 모든 리액트 컴포넌트에 영향을 미칠 수도 있는 무거운 작업이다. + +useLayoutEffect와 같이 렌더링이 완료되기 전에 동작하게 되는데, useLayoutEffect와의 차이점은 DOM의 변경 작업 이전에 실행된다는 것이다. + +> 따로 사용할 일이 없을 것 같긴 하네요. + +### 10.2.2 react-dom/client + +#### createRoot + +기존은 `ReactDOM.render`를 통해 렌더링을 했다. + +리액트 18부터는 `ReactDOM.createRoot`를 통해 렌더링을 할 수 있다. + +> 제가 알기론 concurrent mode를 사용하기 위해서는 `createRoot`를 사용해야 한다고 알고 있슴니다 . . + +#### 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 더욱 엄격해진 엄격 모드 (엄근진) + +#### 리액트의 엄격 모드 + +잠재적인 버그를 미리 찾아내기 위해 리액트의 엄격 모드를 사용할 수 있다. + +무 적 권 켜놓으십쇼. + +> 책에서 strict mode를 통해 검출할 수 있는 안 좋은 예시들을 소개해 주고 있는데, 다행스럽게도 본 경험이 없네요,,! + +### 10.2.6 Suspense 기능 강화 + +기존 `Suspense`는 동작하긴 했지만, 컴포넌트가 보이기 전에 `useEffect`가 실행되는 등의 문제가 있었다. + +더불어 서버에서 사용할 수 없었다. 그렇기에 커스텀한 컴포넌트를 만들어 SSR 환경에서도 지원하게끔 만들어야 했다. + +> Suspense에 스로틀링이 추가됐다는데, 정확하게 무슨 의미?,, + +## 마무리 + +리액트 17과 18의 변경 사항을 살펴봤다. + +핵심은 동시성 렌더링이다. 과거엔 렌더링을 시작하면 끝날 때까지 기다려야 했으나, 리액트 18부터는 렌더링을 중단하고 다른 작업을 할 수 있다. + +이를 통해 발생한 문제인 상태 동기화 문제를 해결하기 위해 새로운 훅들이 추가되었다. + +> 라이브러리 만들 때 고려할 점들이 추가됐네요,,! \ No newline at end of file