React v18.0
이제 npm에서 React 18을 사용할 수 있습니다!
지난 게시물에서 앱을 React 18로 업그레이드하기 위한 단계별 지침을 공유했습니다. 이 게시물에서는 React 18의 새로운 기능과 미래에 대해 어떤 의미를 갖는지에 대한 개요를 제공합니다.
최신 주요 버전에는 automatic batching, startTransition과 같은 새로운 API, Suspense를 지원하는 스트리밍 서버 사이드 렌더링과 같은 즉시 사용 가능한 개선 사항이 포함되어 있습니다.
React 18의 많은 기능은 강력한 새 기능을 잠금 해제하는 배후의 배경인 새로운 동시 렌더러 위에 구축됩니다. Concurrent React는 옵트인입니다. 동시 기능을 사용할 때만 활성화되지만 사람들이 애플리케이션을 구축하는 방식에 큰 영향을 미칠 것이라고 생각합니다.
우리는 React의 동시성에 대한 지원을 연구하고 개발하는데 수년을 보냈으며 기존 사용자에게 점진적인 채택 경로를 제공하기 위해 특별히 주의를 기울였습니다. 지난 여름, 우리는 커뮤니티 전문가들로부터 피드백을 수집하고 전체 React 생태계에 대한 원활한 업그레이드 경험을 보장하기 위해 React 18 워킹 그룹을 구성했습니다.
놓친 경우를 대비하여 React Conf 2021에서 이 비전의 많은 부분을 공유했습니다.
- keynote에서는 React 18이 개발자가 훌륭한 사용자 경험을 쉽게 구축할 수 있도록 하는 우리의 미션에 어떻게 부합하는지 설명합니다.
- Shruti Kapoor는 React 18의 새로운 기능을 사용하는 방법을 시연했습니다.
- Shaundai Person는 Suspense를 사용한 스트리밍 서버 렌더링에 대한 개요를 제공했습니다.
아래는 동시 렌더링부터 시작하여 이 릴리스에서 기대할 수 있는 사항에 대한 전체 개요입니다.
React Native 사용자를 위한 참고 사항: React 18은 새로운 React Native 아키텍처와 함께 React Native로 전달됩니다. 자세한 내용은 여기에서 React Conf keynote를 참고하세요
Concurrent React는 무엇인가?
React 18의 가장 중요한 추가 기능은 여러분이 생각할 필요가 없기를 바라는 동시성입니다. 우리는 이것이 응용 프로그램 개발자에게 대체로 사실이라고 생각하지만 라이브러리 관리자에게는 이야기가 조금 더 복잡할 수 있습니다.
동시성은 그 자체로 기능이 아닙니다. 이는 React가 동시에 여러 버전의 UI를 준비할 수 있도록 하는 새로운 비하인드 메커니즘입니다. 여러분은 동시성을 구현 세부 사항으로 생각할 수 있습니다. 동시성은 잠금을 해제하는 기능 때문에 가치가 있습니다. React는 내부 구현에서 우선 순위 큐 및 다중 버퍼링과 같은 정교한 기술을 사용합니다. 그러나 공개 API에서는 이러한 개념을 볼 수 없습니다.
우리는 API를 설계할 때 구현 세부 정보를 개발자에게 숨기려고 했습니다. React 개발자로서 당신은 사용자 경험이 어떤 모습이기를 원하는지에 집중하고 React는 그 경험을 제공하는 방법을 처리합니다. 따라서 우리는 React 개발자가 내부에서 동시성이 어떻게 작동하는지 알 것으로 기대하지 않습니다.
그러나 Concurrent React는 일반적인 구현 세부 사항보다 더 중요합니다. 이는 React 의 핵심 렌더링 모델에 대한 근본적인 업데이트입니다. 따라서 동시성이 어떻게 작동하는지 아는 것이 매우 중요하지는 않지만 높은 수준에서 동시성이 무엇인지 아는 것은 가치가 있습니다.
Concurrent React의 핵심 속성은 렌더링을 중단할 수 있다는 것입니다. React 18로 처음 업그레이드하면 동시 기능을 추가하기 전에 업데이트가 이전 버전의 React와 동일하게 중단되지 않는 단일 동기 트랜잭션으로 렌더링됩니다. 동시성 기능을 추가하기 전에 React 18로 처음 업그레이드하면 이전 버전의 React와 동일하게 업데이트가 중단되지 않는 단일 동기 트랜잭션으로 렌더링됩니다. 동기적 렌더링은 업데이트가 렌더링을 시작하면 사용자가 화면에서 결과를 볼 수 있을 때까지 아무것도 중단할 수 없습니다.
동시 렌더링에서는 항상 그런 것은 아닙니다. React는 업데이트 렌더링을 시작하고 중간에 일시 중지한 다음 나중에 계속할 수 있습니다. 또한 진행 중인 렌더링을 완전히 포기할 수도 있습니다. React는 렌더링이 중단되더라도 UI가 일관되게 표시되도록 보장합니다. 이를 위해 전체 트리가 평가되면 끝날 때까지 DOM 변형을 수행하기 위해 기다립니다. 이 기능을 통해 React는 메인 스레드를 차단하지 않고 백그라운드에서 새 화면을 준비할 수 있습니다. 이는 UI가 대규모 렌더링 작업 중에 있더라도 사용자 입력에 즉시 응답하여 유동적인 사용자 경험을 생성할 수 있음을 의미합니다.
또 다른 예는 재사용 가능한 상태입니다. Concurrent React는 화면에서 UI 섹션을 제거한 다음 이전 상태를 재사용하면서 나중에 다시 추가할 수 있습니다. 예를 들어, 사용자가 화면에서 탭을 이동했다가 다시 돌아올 때 React는 이전 화면을 이전과 동일한 상태로 복원할 수 있어야 합니다. 다음 마이너 버전에서는 이 패턴을 구현하는 <Offscreen>
이라는 새로운 구성 요소를 추가할 계획입니다. 마찬가지로 오프스크린을 사용하여 백그라운드에서 새 UI를 준비하여 사용자가 표시하기 전에 준비할 수 있습니다.
동시성 렌더링은 React의 강력한 새 도구이며 Suspense, 트랜지션 및 스트리밍 서버 렌더링을 포함하여 대부분의 새로운 기능은 이를 활용하도록 구축되었습니다. 그러나 React 18은 우리가 이 새로운 기반 위에 구축하려는 것의 시작일 뿐입니다.
점진적으로 동시성 기능 채택
기술적으로 동시 렌더링은 혁신적인 변화입니다. 동시 렌더링은 인터럽트가 가능하기 때문에 동시 렌더링이 활성화되면 컴포넌트가 약간 다르게 동작합니다.
테스트에서 수천 개의 컴포넌트를 React 18로 업그레이드했습니다. 우리가 발견한 것은 거의 모든 기존 컴포넌트가 변경 없이 동시성 렌더링으로 “작동”한다는 것입니다. 그러나 일부는 추가 마이그레이션 작업이 필요할 수 있습니다. 일반적으로 변경 사항이 작기는 하지만 원하는 속도로 변경할 수 있습니다. React 18의 새로운 렌더링 동작은 새로운 기능을 사용하는 앱 부분에서만 활성화됩니다.
전반적인 업그레이드 전략은 기존 코드를 중단하지 않고 React 18에서 애플리케이션을 실행하는 것입니다. 그런 다음 원하는 속도로 동시성 기능을 점진적으로 추가할 수 있습니다. <StrictMode>
를 사용하여 개발 중에 동시성 관련 버그를 표면화하는 데 도움을 줄 수 있습니다. Strict Mode는 프로덕션 동작에 영향을 미치지 않지만 개발 중에 멱등성이 있을 것으로 예상되는 추가 경고 및 이중 호출 기능을 기록합니다. 이것은 모든 것을 잡을 수는 없지만 가장 일반적인 유형의 실수를 방지하는 데 효과적입니다.
React 18로 업그레이드하면 동시 기능을 즉시 사용할 수 있습니다. 예를 들어 startTransition을 사용하여 사용자 입력을 차단하지 않고 화면 사이를 탐색할 수 있습니다. 또는 useDeferredValue를 사용하여 비용이 많이 드는 리렌더링을 조절합니다.
그러나 장기적으로 앱에 동시성을 추가하는 주요 방법은 동시성 지원 라이브러리 또는 프레임워크를 사용하는 것입니다. 대부분의 경우 동시성 API들과 직접 상호작용하지 않습니다. 예를 들어 개발자가 새 화면으로 이동할 때마다 startTransition을 호출하는 대신 라우터 라이브러리는 네비게이션을 자동으로 startTransition으로 래핑합니다.
라이브러리가 동시성과 호환 가능하도록 업그레이드하는데 다소 시간이 걸릴 수 있습니다. 우리는 라이브러리가 동시성 기능을 더 쉽게 활용할 수 있도록 새로운 API를 제공했습니다. 그 동안 React 생태계를 점진적으로 마이그레이션하기 위해 작업하는 동안 관리자를 기다려주세요.
자세한 내용은 이전 게시물인 React 18로 업그레이드하는 방법을 참조하세요.
데이터 프레임워크에서의 Suspense
React 18에서는 Relay, Next.js, Hydrogen 또는 Remix와 같은 독창적인 프레임워크에서 데이터 가져오기를 위해 Suspense를 사용할 수 있습니다. Suspense를 사용한 데이터 가져오기는 기술적으로는 가능하지만 여전히 일반적인 전략으로는 권장되지 않습니다.
향후에는 독단적인 프레임워크를 사용하지 않고도 Suspense를 사용하여 데이터에 더 쉽게 접근할 수 있는 추가 프리미티브를 공개할 수 있습니다. 그러나 Suspense는 라우터, 데이터 계층 및 서버 렌더링 환경과 같은 애플리케이션 아키텍처에 깊이 통합될 때 가장 잘 작동합니다. 따라서 장기적으로도 라이브러리와 프레임워크가 React 생태계에서 중요한 역할을 할 것으로 기대합니다.
이전 버전의 React에서와 마찬가지로 React.lazy를 사용하여 클라이언트에서 코드 분할을 위해 Suspense를 사용할 수도 있습니다. 하지만 Suspense에 대한 우리의 비전은 항상 코드를 로드하는 것 이상이었습니다. 목표는 결국 동일한 선언적 Suspense fallback이 모든 비동기 작업(코드 로드, 데이터, 이미지 등)을 처리할 수 있도록 Suspense에 대한 지원을 확장하는 것입니다.
Server Components는 아직 개발 중 입니다
Server Components는 개발자가 기존 서버 렌더링의 향상된 성능과 클라이언트 측즈 앱의 풍부한 상호 작용을 결합하여 서버와 클라이언트에 걸쳐 있는 앱을 구축할 수 있도록 하는 향후 기능입니다. 서버 컴포넌트는 본질적으로 Concurrent React와 결합되지 않지만 Suspense 및 스트리밍 서버 렌더링과 같은 동시 기능과 가장 잘 작동하도록 설계되었습니다.
서버 컴포넌트는 아직 실험적이지만 마이너 18.x 릴리즈에서 초기 버전을 릴리즈할 예정입니다. 그 동안 우리는 Next.js, Hydrogen 및 Remix와 같은 프레임워크와 협력하여 제안을 발전시키고 광범위하게 채택될 수 있도록 준비하고 있습니다.
React 18의 새로운 기능
새로운 기능: Automatic Batching
Batching은 React가 성능 향상을 위해 여러 상태 업데이트를 단일 재렌더링으로 그룹화하는 것입니다. 자동 automatic batching 없이 React 이벤트 핸들러 내 업데이트만 automatic batching했습니다. Promise 안에서의 업데이트들, setTimeout, 네이티브 이벤트 핸들러, 또는 기타 이벤트 내부의 업데이트는 기본적으로 React에서 일괄처리되지 않습니다. Automatic batching을 사용하면 다음 업데이트가 자동으로 일괄 처리됩니다.
// 이전: React 이벤트만 일괄 처리되었습니다.
setTimeout(() => {
setCount(c => c + 1);
setFlag(f => !f);
// React는 각 상태 업데이트에 대해 한 번씩 두 번 렌더링합니다(일괄 처리 없음).
}, 1000);
// 이후: 타임아웃이나 promise 안에 있는 업데이트,
// 네이티브 이벤트 핸들러 또는 기타 이벤트는 일괄 처리됩니다.
setTimeout(() => {
setCount(c => c + 1);
setFlag(f => !f);
// React는 마지막에 한 번만 다시 렌더링합니다(이게 batching입니다!).
}, 1000);
자세한 내용은 React 18에서 더 적은 렌더링을 위한 자동 일괄 처리에 대한 게시물을 참조하세요.
새로운 기능: Transitions
Transition은 긴급 업데이트와 긴급하지 않은 업데이트를 구분하기 위한 React의 새로운 개념입니다.
- 긴급 업데이트는 입력, 클릭, 누르기 등과 같은 직접적인 상호 작용을 반영합니다.
- 전환 업데이트는 UI를 한 뷰에서 다른 뷰로 전환합니다.
타이핑, 클릭 또는 누르기와 같은 긴급 업데이트는 물리적 개체의 작동 방식에 대한 직관과 일치하도록 즉각적인 응답이 필요합니다. 그렇지 않으면 그들은 “틀렸다”고 느낍니다. 그러나 전환은 사용자가 화면에서 모든 중간 값을 볼 것으로 기대하지 않기 때문에 다릅니다.
예를 들어 드롭다운 필터를 선택하면 필터 버튼 자체가 클릭시 즉시 응답할 것을 예상합니다. 그러나 실제 결과는 별도로 전환될 수 있습니다. 약간의 지연은 눈에 띄지 않으며 종종 예상됩니다. 결과 렌더링이 완료되기 전에 필터를 다시 변경하면 최신 결과만 볼 수 있습니다.
일반적으로 최상의 사용자 경험을 위해 단일 사용자 입력으로 긴급 업데이트와 긴급하지 않은 업데이트가 모두 생성되어야 합니다. 입력 이벤트 내에서 startTransition API를 사용하여 어떤 업데이트가 긴급하고 “transitions”인지 React에 알릴 수 있습니다.
import {startTransition} from 'react';
// 긴급: 입력한 내용 표시
setInputValue(input);
// 내부의 모든 상태 업데이트를 전환으로 표시
startTransition(() => {
// 전환: 결과 표시
setSearchQuery(input);
});
startTransition에 래핑된 업데이트는 긴급하지 않은 것으로 처리되며 클릭이나 키 누름과 같은 더 긴급한 업데이트가 들어오면 중단됩니다. 전환이 사용자에 의해 중단되면(예를 들어 연속으로 여러 문자를 입력하여)React는 완료되지 않은 오래된 렌더링 작업을 버리고 최신 업데이트만 렌더링합니다.
useTransition
: 보류된 상태를 추적하는 값을 포함하여 transition을 시작하는 훅.startTransition
: 훅을 사용할 수 없을 때 transition을 시작하는 방법.
Transition은 동시성 렌더링을 선택하여 업데이트를 중단할 수 있습니다. 콘텐츠가 다시 일시 중지되면 transition은 백그라운드에서 transition 콘텐츠를 렌더링하는 동안 현재 콘텐츠를 계속 표시하도록 React에 지시합니다 (자세한 내용은 Suspense RFC을 참조하세요).
새로운 Suspense 기능
Suspense를 사용하면 아직 표시할 준비가 되지 않은 경우 컴포넌트 트리의 일부에 대한 로드 상태를 선언적으로 지정할 수 있습니다.
<Suspense fallback={<Spinner />}>
<Comments />
</Suspense>
Suspense는 “UI 로딩 상태”를 React 프로그래밍 모델의 일급 선언적 개념으로 만듭니다. 이를 통해 우리는 그 위에 더 높은 수준의 기능을 구축할 수 있습니다.
우리는 몇 년 전에 제한된 버전의 Suspense를 소개했습니다. 그러나 지원되는 유일한 사용 사례는 React.lazy를 사용한 코드 분할이며 서버에서 렌더링할 때 전혀 지원되지 않았습니다.
React 18에서는 서버에 Suspense 지원을 추가하고 동시 렌더링 기능을 사용하여 기능을 확장했습니다.
React 18의 Suspense는 transition API와 결합할 때 가장 잘 동작합니다. 만약 여러분이 전환 중에 일시 중지시킨다면 React는 이미 표시된 콘텐츠가 대체 콘텐츠로 대체되는 것을 방지합니다. 대신 React는 잘못된 로딩 상태를 방지하기 위해 충분한 데이터가 로드될 때까지 렌더링을 지연시킵니다.
자세한 내용은 React 18의 Suspense에 대한 RFC를 참조하세요.
새로운 클라이언트 및 서버 렌더링 API
이 릴리즈에는 우리는 클라이언트와 서버에서 렌더링하기 위해 노출하는 API를 재설계할 기회를 가졌습니다. 이러한 변경 사항을 통해 사용자는 React 18에서 새 API로 업그레이드하는 동안 React 17 모드에서 이전 API를 계속 사용할 수 있습니다.
React DOM Client
이러한 새 API는 이제 react-dom/client
에서 내보냅니다.
createRoot
:렌더링
하거나언마운트
할 루트를 만드는 새로운 방법입니다.ReactDOM.render
대신 사용하십시오. React 18의 새로운 기능은 그것 없이는 작동하지 않습니다.hydrateRoot
: 서버 렌더링 애플리케이션을 hydrate하는 새로운 방법입니다. 새로운 React DOM 서버 API와 함께ReactDOM.hydrate
대신 사용하십시오. React 18의 새로운 기능은 그것 없이는 작동하지 않습니다.
createRoot
와 hydrateRoot
모두 React가 렌더링 또는 로깅을 위한 hydrate중에 오류를 복구할 때 알림을 받으려는 경우 onRecoveralbeError
라는 새 옵션을 허용합니다. 기본적으로 React는 reportError
또는 구형 브라우저에서 console.error
를 사용합니다.
여기에서 React DOM Server 문서를 참조하세요.
React DOM Server
이러한 새 API는 이제 react-dom/server
에서 내보내지고 서버에서 Suspense 스트리밍을 완벽하게 지원합니다.
renderToPipeableStream
: 노드 환경에서 스트리밍용.renderToReadableStream
: Deno 및 Cloudflare 작업자와 같은 최신 에지 런타임 환경용.
기존 renderToString
메서드는 계속 작동하지만 사용하지 않는 것이 좋습니다.
여기에서 React DOM Server 문서를 참조하세요.
새로운 Strict Mode 동작
미래에는 React가 상태를 유지하면서 UI 섹션을 추가하고 제거할 수 있는 기능을 추가하고 싶습니다. 예를 들어, 사용자가 화면을 탭하여 이동하면 React는 즉시 이전 화면을 표시할 수 있어야 합니다. 이를 위해 React는 이전과 동일한 컴포넌트 상태를 이용하여 트리를 마운트 해제하고 다시 마운트합니다.
이 기능은 React 앱에 즉시 사용 가능한 더 나은 성능을 제공하지만 컴포넌트가 여러 번 마운트되고 제거되는 효과에 탄력적이어야 합니다. 대부분의 효과는 변경 없이 작동하지만 일부 효과는 한 번만 장착되거나 파괴된다고 가정합시다.
이러한 문제를 표면화하는 데 도움이 되도록 React 18은 Strict Mode에 대한 새로운 개발 전용 검사를 도입합니다. 이 새로운 검사는 컴포넌트가 처음으로 마운트될 때마다 자동으로 모든 컴포넌트를 마운트 해제하고 다시 마운트하여 두 번째 마운트에서 이전 상태를 복원합니다.
이 변경 전에 React는 컴포넌트를 마운트하고 효과를 생성했습니다.
* React mounts the component.
* Layout effects are created.
* Effects are created.
React 18의 Strict Mode를 사용하면 React는 개발 모드에서 구성 요소의 마운트 해제 및 리마운트를 시뮬레이션합니다.
* React mounts the component.
* Layout effects are created.
* Effects are created.
* React simulates unmounting the component.
* Layout effects are destroyed.
* Effects are destroyed.
* React simulates mounting the component with the previous state.
* Layout effects are created.
* Effects are created.
여기에서 재사용 가능한 상태를 보장하는 문서를 참조하세요.
New Hooks
useId
useId
는 hydration 불일치를 피하면서 클라이언트와 서버 모두에서 고유 ID를 생성하기 위한 새로운 훅입니다. 고유 ID가 필요한 접근성 API와 통합되는 컴포넌트 라이브러리에 주로 유용합니다. 이는 React 17 이하에 이미 존재하는 문제를 해결하지만 새로운 스트리밍 서버 렌더러가 HTML을 순서없이 전달하는 방식 때문에 React 18에서 훨씬 더 중요합니다. 여기에서 문서를 참조하십시오.
Note
useId
는 목록에서 키를 생성하기 위한 것이 아닙니다. 키는 데이터에서 생성되어야 합니다.
useTransition
useTransition
과 startTransition
을 사용하면 일부 상태 업데이트를 긴급하지 않은 것으로 표시할 수 있습니다. 다른 상태 업데이트는 기본적으로 긴급한 것으로 간주됩니다. React는 긴급하지 않은 상태 업데이트(예: 검색 결과 목록 렌더링)를 중단하기 위해 긴급한 상태 업데이트(예: 텍스트 입력 업데이트)를 허용합니다. 이 문서를 참조하세요
useDeferredValue
useDeferredValue
를 사용하면 트리의 긴급하지 않은 부분을 다시 렌더링하는 것을 연기할 수 있습니다. 이는 디바운싱과 비슷하지만 그에 비해 몇 가지 장점이 있습니다. 고정된 지연 시간이 없으므로 React는 첫 번째 렌더링이 화면에 반영된 직후 지연 렌더링을 시도합니다. 지연된 렌더링은 중단 가능하며 사용자 입력을 차단하지 않습니다. 이 문서를 참조하세요.
useSyncExternalStore
useSyncExternalStore
는 저장소에 대한 업데이트를 강제로 동기화하여 외부 저장소가 동시 읽기를 지원할 수 있도록 하는 새로운 훅입니다. 외부 데이터 소스에 대한 구독을 구현할 때 useEffect의 필요성을 제거하고 React 외부의 상태와 통합되는 모든 라이브러리에 권장됩니다. 이 문서를 참조하세요.
Note
useSyncExternalStore
는 애플리케이션 코드가 아닌 라이브러리에서 사용하기 위한 것입니다.
useInsertionEffect
useInsertionEffect
는 CSS-in-JS 라이브러리가 렌더링에 스타일 삽입의 성능 문제를 해결할 수 있도록 하는 새로운 훅입니다. 이미 CSS-in-JS 라이브러리를 구축하지 않았다면 이것을 사용하지 않을 것이라고 기대합니다. 이 훅은 DOM이 변경된 후 실행되지만 레이아웃 효과가 새 레이아웃을 읽기 전에 실행됩니다. 이것은 React 17 이하에 이미 존재하는 문제를 해결하지만 React 18에서는 React가 동시 렌더링 중에 브라우저에 양보하여 레이아웃을 다시 계산할 수 있는 기회를 주기 때문에 훨씬 더 중요합니다. 이 문서를 참조하세요.
Note
useInsertionEffect
는 애플리케이션 코드가 아닌 라이브러리에서 사용하기 위한 것입니다.
How to Upgrade
단계별 지침과 주요 변경 사항 및 주목할 만한 변경 사항의 전체 목록은 React 18로 업그레이드 하는 방법을 참조하세요.
Changelog
React
- Add
useTransition
anduseDeferredValue
to separate urgent updates from transitions. (#10426, #10715, #15593, #15272, #15578, #15769, #17058, #18796, #19121, #19703, #19719, #19724, #20672, #20976 by @acdlite, @lunaruan, @rickhanlonii, and @sebmarkbage) - Add
useId
for generating unique IDs. (#17322, #18576, #22644, #22672, #21260 by @acdlite, @lunaruan, and @sebmarkbage) - Add
useSyncExternalStore
to help external store libraries integrate with React. (#15022, #18000, #18771, #22211, #22292, #22239, #22347, #23150 by @acdlite, @bvaughn, and @drarmstr) - Add
startTransition
as a version ofuseTransition
without pending feedback. (#19696 by @rickhanlonii) - Add
useInsertionEffect
for CSS-in-JS libraries. (#21913 by @rickhanlonii) - Make Suspense remount layout effects when content reappears. (#19322, #19374, #19523, #20625, #21079 by @acdlite, @bvaughn, and @lunaruan)
- Make
<StrictMode>
re-run effects to check for restorable state. (#19523 , #21418 by @bvaughn and @lunaruan) - Assume Symbols are always available. (#23348 by @sebmarkbage)
- Remove
object-assign
polyfill. (#23351 by @sebmarkbage) - Remove unsupported
unstable_changedBits
API. (#20953 by @acdlite) - Allow components to render undefined. (#21869 by @rickhanlonii)
- Flush
useEffect
resulting from discrete events like clicks synchronously. (#21150 by @acdlite) - Suspense
fallback={undefined}
now behaves the same asnull
and isn’t ignored. (#21854 by @rickhanlonii) - Consider all
lazy()
resolving to the same component equivalent. (#20357 by @sebmarkbage) - Don’t patch console during first render. (#22308 by @lunaruan)
- Improve memory usage. (#21039 by @bgirard)
- Improve messages if string coercion throws (Temporal.*, Symbol, etc.) (#22064 by @justingrant)
- Use
setImmediate
when available overMessageChannel
. (#20834 by @gaearon) - Fix context failing to propagate inside suspended trees. (#23095 by @gaearon)
- Fix
useReducer
observing incorrect props by removing the eager bailout mechanism. (#22445 by @josephsavona) - Fix
setState
being ignored in Safari when appending iframes. (#23111 by @gaearon) - Fix a crash when rendering
ZonedDateTime
in the tree. (#20617 by @dimaqq) - Fix a crash when document is set to
null
in tests. (#22695 by @SimenB) - Fix
onLoad
not triggering when concurrent features are on. (#23316 by @gnoff) - Fix a warning when a selector returns
NaN
. (#23333 by @hachibeeDI) - Fix a crash when document is set to
null
in tests. (#22695 by @SimenB) - Fix the generated license header. (#23004 by @vitaliemiron)
- Add
package.json
as one of the entry points. (#22954 by @Jack) - Allow suspending outside a Suspense boundary. (#23267 by @acdlite)
- Log a recoverable error whenever hydration fails. (#23319 by @acdlite)
React DOM
- Add
createRoot
andhydrateRoot
. (#10239, #11225, #12117, #13732, #15502, #15532, #17035, #17165, #20669, #20748, #20888, #21072, #21417, #21652, #21687, #23207, #23385 by @acdlite, @bvaughn, @gaearon, @lunaruan, @rickhanlonii, @trueadm, and @sebmarkbage) - Add selective hydration. (#14717, #14884, #16725, #16880, #17004, #22416, #22629, #22448, #22856, #23176 by @acdlite, @gaearon, @salazarm, and @sebmarkbage)
- Add
aria-description
to the list of known ARIA attributes. (#22142 by @mahyareb) - Add
onResize
event to video elements. (#21973 by @rileyjshaw) - Add
imageSizes
andimageSrcSet
to known props. (#22550 by @eps1lon) - Allow non-string
<option>
children ifvalue
is provided. (#21431 by @sebmarkbage) - Fix
aspectRatio
style not being applied. (#21100 by @gaearon) - Warn if
renderSubtreeIntoContainer
is called. (#23355 by @acdlite)
React DOM Server
- Add the new streaming renderer. (#14144, #20970, #21056, #21255, #21200, #21257, #21276, #22443, #22450, #23247, #24025, #24030 by @sebmarkbage)
- Fix context providers in SSR when handling multiple requests. (#23171 by @frandiox)
- Revert to client render on text mismatch. (#23354 by @acdlite)
- Deprecate
renderToNodeStream
. (#23359 by @sebmarkbage) - Fix a spurious error log in the new server renderer. (#24043 by @eps1lon)
- Fix a bug in the new server renderer. (#22617 by @shuding)
- Ignore function and symbol values inside custom elements on the server. (#21157 by @sebmarkbage)
React DOM Test Utils
- Throw when
act
is used in production. (#21686 by @acdlite) - Support disabling spurious act warnings with
global.IS_REACT_ACT_ENVIRONMENT
. (#22561 by @acdlite) - Expand act warning to cover all APIs that might schedule React work. (#22607 by @acdlite)
- Make
act
batch updates. (#21797 by @acdlite) - Remove warning for dangling passive effects. (#22609 by @acdlite)
React Refresh
- Track late-mounted roots in Fast Refresh. (#22740 by @anc95)
- Add
exports
field topackage.json
. (#23087 by @otakustay)