Home
PostsAbout
react

번역) React 19 Beta Upgrade Guide

React 19 베타 업그레이드 가이드

2024-08-20

본문: https://react.dev/blog/2024/04/25/react-19-upgrade-guide

React 19에 추가되는 개선 사항은 꽤나 큰 변화를 요구합니다. 하지만, 우리는 대부분의 앱에게 영향(impact)이 없도록 최대한 원만하게 React 19로 업그레이드할 수 있도록 노력하고 있습니다. 이번 포스트에서 우리는 React 19 베타 버전으로 업그레이드하기 위한 과정을 가이드합니다.

2024년 4월 26일 by Ricky Hanlon


💡 베타 릴리즈 버전은 React 19를 위한 준비하기 위한 용도입니다. 개발자들은 React의 버전을 18.3.0으로 업그레이드하고 우리가 피드백을 바탕으로 React를 개선하여 stable한 19 버전을 내놓기까지 기다릴 필요가 있습니다.

React 19에 추가되는 개선 사항은 꽤나 큰 변화를 요구합니다. 하지만, 우리는 대부분의 앱에게 영향(impact)이 없도록 최대한 원만하게 React 19로 업그레이드할 수 있도록 노력하고 있습니다.

업그레이드를 보다 쉽게 하기 위해, 오늘 우리는 React 18.3 버전을 출시합니다.

💡 React 18.3 버전이 출시되었습니다.

React 19 버전으로 업그레이드하는 과정을 용이하게 하기 위해, 우리는 react@18.3 을 출시하였습니다. react@18.3 은 18.2 버전과 동일하나, deprecated된 API들에 대한 경고와 React 19 버전에 필요한 몇 가지 변경 사항을 추가하였습니다.

우리는 React 19 버전으로 업그레이드하기 전에 발생하는 어떤 이슈들을 확인하기 위해 React 18.3 버전으로 업그레이드하는 것을 추천합니다.

18.3 버전의 변경점이 궁금하다면, Release Notes를 참고하세요.

이번 포스트에서 우리는 React 19 베타 버전으로 업그레이드하기 위한 과정을 가이드합니다.

우리가 React 19를 테스트하는 것을 돕고 싶으시다면, 이 업그레이드 가이드를 따르고 당신이 마주하는 어떠한 이슈든지 제보(report any issues)해주세요. React 19에 새롭게 추가되는 기능들이 궁금하다면, React 19 release post 포스트를 보시길 바랍니다.


Installing

💡 새로운 JSX Transform이 요구됩니다

우리는 2020년에 React를 import하지 않아도 JSX 구문을 사용할 수 있고 번들 사이즈를 개선할 수 있는 new JSX transform를 공개하였습니다. React 19에서 우리는 ref를 prop으로 사용하고 JSX의 속도를 개선하는 등의 몇 가지 개선사항을 추가합니다. 그리고 그 개선사항은 new transform을 필요로 합니다.

만약 new transform이 활성화되어있지 않다면, 다음과 같은 오류를 마주하게 됩니다.

Your app (or one of its dependencies) is using an outdated JSX transform. Update to the modern JSX transform for faster performance: https://react.dev/link/new-jsx-transform

이미 대부분의 환경에서 new transform이 활성화돼있기 때문에 대부분의 App에 영향을 끼치지는 않을 것이라고 예상합니다. 업그레이드 방법에 대한 메뉴얼 지시가 필요하다면, announcement post을 봐주시길 바랍니다.

최신 버전의 React와 React DOM을 설치하기 위해서는:

npm install react@beta react-dom@beta

만약 TypeScript를 사용하고 있다면, types 또한 업데이트해야 합니다. React 19가 stable 버전으로 출시된 이후부터는 types 또한 기존에 설치하던 방법대로 (@types/react , @types/react-dom )설치할 수 있습니다. 베타 기간 동안에는 types를 다른 방법으로 설치할 수 있습니다.

{
  "dependencies": {
    "@types/react": "npm:types-react@beta",
    "@types/react-dom": "npm:types-react-dom@beta"
  },
  "overrides": {
    "@types/react": "npm:types-react@beta",
    "@types/react-dom": "npm:types-react-dom@beta"
  }
}

우리는 대부분의 replacements를 위한 codemod 또한 포함하고 있습니다. TypeScript changes을 참조하세요.

Breaking changes

Errors in render are not re-thrown

이전 React 버전에서는, 렌더링 과정에서 던져진 에러가 잡히고 다시 던져졌습니다(errors thrown during render were caught and rethrown). DEV 모드에서는 console.error 를 통해서 로그를 찍습니다. 그래서 에러 로그가 중복해서 발생합니다.

React 19에서 우리는 에러를 핸들링하는 방법(improved how errors are handled)을 개선하여 중복된 에러 로그가 생기지 않도록 하였습니다.

  • Uncaught Errors: Error Boundary에 잡히지 않는 에러는 window.reportError 에 보고됩니다.
  • Caught Errors: Error Boundary에 잡히는 에러는 console.error 에 보고됩니다.

대부분의 기존 App들에 영향이 미치지는 않겠지만, 상용 코드의 에러 리포팅이 rethrown에 의존한다면 당신의 에러 핸들링 방식을 수정해야할 수도 있습니다. 이것을 지원하기 위해서, 우리는 createRoothydrateRoot 에 새로운 메서드들을 추가하여 에러 핸들링을 커스텀할 수 있게 하였습니다.

const root = createRoot(container, {
  onUncaughtError: (error, errorInfo) => {
    // ... log error report
  },
  onCaughtError: (error, errorInfo) => {
    // ... log error report
  }
});

더 많은 정보를 원하신다면, createRoothydrateRoot 의 공식문서를 보시길 권합니다.

Removed deprecated React APIs

Removed: propTypes and defaultProps for function

PropTypesApril 2017 (v15.5.0)에 deprecated되었습니다.

React 19에서 우리는 React 패키지에서 propType 체크를 제거하고, 해당 기능을 이용하는 것을 조용히 무시하도록(silently ignored) 하였습니다. 만약 당신이 propTypes를 사용하고 있다면, propTypes로부터 TypeScript나 혹은 다른 타입 체킹 솔루션으로 이전하는 것을 권합니다.

또한 ES6 기본 매개변수 대신 함수 컴포넌트에서 defaultProps를 제거합니다. 클래스 컴포넌트는 ES6를 대체할 수 없으므로 defaultProps를 계속 지원할 것입니다.

// Before
import PropTypes from 'prop-types';

function Heading({text}) {
  return <h1>{text}</h1>;
}
Heading.propTypes = {
  text: PropTypes.string,
};
Heading.defaultProps = {
  text: 'Hello, world!',
};
// After
interface Props {
  text?: string;
}
function Heading({text = 'Hello, world!'}: Props) {
  return <h1>{text}</h1>;
}

Removed: Legacy Context using contextTypes and getChildContext

Legacy Context는 October 2018 (v16.6.0)에 deprecated되었습니다.

Legacy Context는 클래스 컴포넌트에서만 contextTypesgetChildContext API를 이용해서 사용할 수 있었습니다. 그리고 쉽게 놓칠 수 있는 약간의 버그 때문에 contextType 에 의해 대체되었습니다. React 19에서 우리는 React를 조금은 더 가볍고 빠르게 만들기 위해서 Legacy Context를 제거합니다.

만약 당신이 여전히 클래스 컴포넌트에서 Legacy Context를 사용하고 있다면, 새로운 contextType API로 이전하는 것이 필요합니다.

// Before
import PropTypes from 'prop-types';

class Parent extends React.Component {
  static childContextTypes = {
    foo: PropTypes.string.isRequired,
  };

  getChildContext() {
    return { foo: 'bar' };
  }

  render() {
    return <Child />;
  }
}

class Child extends React.Component {
  static contextTypes = {
    foo: PropTypes.string.isRequired,
  };

  render() {
    return <div>{this.context.foo}</div>;
  }
}
// After
const FooContext = React.createContext();

class Parent extends React.Component {
  render() {
    return (
      <FooContext value='bar'>
        <Child />
      </FooContext>
    );
  }
}

class Child extends React.Component {
  static contextType = FooContext;

  render() {
    return <div>{this.context}</div>;
  }
}

Removed: string refs

String refs는 March, 2018 (v16.3.0)에 deprecated되었습니다.

클래스 컴포넌트는 다수의 단점(multiple downsides) 때문에 string refs가 ref callbacks에 의해 대체되기 전까지 string refs를 지원하였습니다. React 19에서 우리는 React를 조금 더 이해하기 단순하고 쉽게 만들기 위해 string refs를 삭제합니다.

만약 당신이 아직 클래스 컴포넌트에서 string refs를 사용하고 있다면, ref callbacks로 이전할 필요가 있습니다.

// Before
class MyComponent extends React.Component {
  componentDidMount() {
    this.refs.input.focus();
  }

  render() {
    return <input ref='input' />;
  }
}
class MyComponent extends React.Component {
  componentDidMount() {
    this.input.focus();
  }

  render() {
    return <input ref={input => this.input = input} />;
  }
}

💡 마이그레이션을 돕기 위해서, 우리는 react-codemod을 배포함으로써 자동으로 string refs를 ref callbacks으로 교체되도록 할 예정입니다. this PR을 참고하여 시도해보세요.

Removed: Module pattern factories

Module pattern factories는 August 2019 (v16.9.0)에 deprecated되었습니다.

이 패턴은 흔히 사용되는 패턴은 아니었고, 불필요하게 React를 느리게하고 번들 사이즈를 다소 크게 만들었습니다. React 19에서 우리는 module pattern factories에 대한 지원을 중단할 예정이고, 당신은 regular functions으로 이전할 필요가 있습니다.

// Before
function FactoryComponent() {
  return { render() { return <div />; } }
}
// After
function FactoryComponent() {
  return <div />;
}

Removed: React.createFactory

createFactoryFebruary 2020 (v16.13.0)에 deprecated되었습니다.

JSX 지원 이전에는 createFactory 를 사용하는 것은 흔한 일이었습니다. 그러나 오늘날에는 거의 쓰이지 않고 JSX에 의해 그 역할이 대체되었습니다. React 19에서 우리는 createFactory 를 삭제할 예정이고, 당신은 JSX로 이전할 필요가 있습니다.

// Before
import { createFactory } from 'react';

const button = createFactory('button');
// After
const button = <button />;

Removed: react-test-renderer/shallow 

React 18에서 우리는 react-shallow-renderer을 re-export하기 위해서 react-test-renderer/shallow을 업데이트하였습니다. React 19에서 우리는 react-test-renderer/shallow을 제거함으로써 패키지를 직접 설치하도록 하였습니다.

npm install react-shallow-renderer --save-dev
- import ShallowRenderer from 'react-test-renderer/shallow';
+ import ShallowRenderer from 'react-shallow-renderer';

💡 shallow rendering을 다시 고려해보세요.

Shallow rendering은 React internals에 의존하며 미래의 업그레이드를 막을 수도 있습니다. 우리는 당신의 테스트를 @testing-library/react@testing-library/react-native로 이전하는 것을 추천합니다.

Removed deprecated React DOM APIs

Removed: react-dom/test-utils

우리는 actreact-dom/test-utils 로부터 react 패키지로 옮겼습니다.

ReactDOMTestUtils.act is deprecated in favor of React.act. Import act from react instead of react-dom/test-utils. See https://react.dev/warnings/react-dom-test-utils for more info.

이 경고를 수정하기 위해서, actreact로부터 import할 수 있습니다.

- import {act} from 'react-dom/test-utils'
+ import {act} from 'react';

다른 모두 test-utils 함수는 삭제되었습니다. 이러한 유틸리티는 흔하지 않았고, 컴포넌트와 React의 낮은 수준의 구현 세부 사항에 너무 쉽게 의존하게 만들었습니다. React 19에서는 이러한 함수가 호출될 때 오류가 발생하며 향후 버전에서 내보내기가 제거될 예정입니다.

대체하는 방법을 보려면 warning page을 참고하세요.

Removed: ReactDOM.render 

ReactDOM.renderMarch 2022 (v18.0.0)에 deprecated되었습니다. React 19에서는 ReactDOM.render 를 제거할 예정이며 ReactDOM.createRoot 로 이전이 필요합니다.

// Before
import {render} from 'react-dom';
render(<App />, document.getElementById('root'));

// After
import {createRoot} from 'react-dom/client';
const root = createRoot(document.getElementById('root'));
root.render(<App />);

Removed: ReactDOM.hydrate

ReactDOM.hydrateMarch 2022 (v18.0.0)에 deprecated되었습니다. React 19에서는 ReactDOM.hydrate 를 제거할 예정이며 ReactDOM.hydrateRoot 를 대신 사용해야 합니다.

// Before
import {hydrate} from 'react-dom';
hydrate(<App />, document.getElementById('root'));

// After
import {hydrateRoot} from 'react-dom/client';
hydrateRoot(document.getElementById('root'), <App />);

Removed: unmountComponentAtNode

ReactDOM.unmountComponentAtNodeMarch 2022 (v18.0.0)에 deprecated되었습니다. React 19에서는 대신 root.unmount() 를 사용해야 합니다.

// Before
unmountComponentAtNode(document.getElementById('root'));

// After
root.unmount();

createRoothydrateRoot 에서 root.unmount() 에 대한 더 많은 정보를 얻을 수 있습니다.

Removed: ReactDOM.findDOMNode

ReactDOM.findDOMNodeOctober 2018 (v16.6.0)에 deprecated되었습니다.

findDOMNode 는 실행 속도가 느린 legacy escape hatch일 뿐만 아니라, 리팩토링에 취약하고, 첫번째 자식 노드만을 리턴하고, abstraction levels를 망가뜨렸기 때문에(see more here) 그것을 제거하기로 하였습니다. 당신은 ReactDOM.findDOMNodeDOM refs로 대체할 수 있습니다.

// Before
import {findDOMNode} from 'react-dom';

function AutoselectingInput() {
  useEffect(() => {
    const input = findDOMNode(this);
    input.select()
  }, []);

  return <input defaultValue="Hello" />;
}
// After
function AutoselectingInput() {
  const ref = useRef(null);
  useEffect(() => {
    ref.current.select();
  }, []);

  return <input ref={ref} defaultValue="Hello" />
}

New deprecations

Deprecated: element.ref

React 19는 ref as a prop을 지원합니다. 따라서 element.props.ref 대신 element.ref를 더 이상 사용하지 않습니다.

element.ref에 액세스하면 경고가 표시됩니다:

Accessing element.ref is no longer supported. ref is now a regular prop. It will be removed from the JSX Element type in a future release.

Deprecated: react-test-renderer

react-test-renderer는 사용자가 사용하는 환경과 일치하지 않는 자체 렌더러 환경을 구현하고, 테스트 구현 세부 사항을 촉진하며, React 내부에 대한 내성 검사에 의존하기 때문에 더 이상 사용되지 않습니다.

테스트 렌더러는 React Testing Library와 같은 더 실용적인 테스트 전략이 나오기 전에 만들어졌으며, 이제는 최신 테스트 라이브러리를 사용할 것을 권장합니다.

React 19에서 react-test-renderer는 사용 중단 경고를 기록하며 동시 렌더링으로 전환되었습니다. 최신의 잘 지원되는 테스트 환경을 위해 테스트를 @testing-library/react 또는 @testing-library/react-native로 마이그레이션하는 것이 좋습니다.

Notable Changes

StrictMode changes

React 19에는 Strict 모드에 대한 몇 가지 수정 및 개선 사항이 포함되어 있습니다.

개발 중 Strict 모드에서 이중 렌더링(double rendering)을 할 때, useMemouseCallback은 두 번째 렌더링 중에 첫 번째 렌더링의 메모화된 결과를 재사용합니다. 이미 Strict Mode와 호환되는 컴포넌트는 동작의 차이를 느끼지 못할 것입니다.

모든 Strict Mode 동작과 마찬가지로 이러한 기능은 개발 중에 컴포넌트의 버그를 사전에 발견하여 프로덕션에 배포하기 전에 수정할 수 있도록 설계되었습니다. 예를 들어, 개발 중에 Strict Mode는 초기 마운트 시 ref callback functions를 두 번 호출하여 마운트된 컴포넌트가 Suspense Fallback으로 대체될 때 발생하는 상황을 시뮬레이션합니다.

UMD builds removed

과거에는 빌드 단계 없이 React를 로드하는 편리한 방법으로 UMD가 널리 사용되었습니다. 이제 HTML 문서에서 스크립트로 모듈을 로드하는 최신 대안이 있습니다. React 19부터는 테스트 및 릴리스 프로세스의 복잡성을 줄이기 위해 더 이상 UMD 빌드를 생성하지 않습니다.

스크립트 태그로 React 19를 로드하려면 esm.sh와 같은 ESM 기반 CDN을 사용하는 것이 좋습니다.

<script type="module">
  import React from "https://esm.sh/react@19/?dev"
  import ReactDOMClient from "https://esm.sh/react-dom@19/client?dev"
  ...
</script>

Libraries depending on React internals may block upgrades

이번 릴리스에는 SECRET_INTERNALS_ DO_NOT_USE_OR_YOU_WILL_BE_FIRED 와 같은 internals을 사용하지 말라는 요청을 무시하는 라이브러리에 영향을 줄 수 있는 React 내부 변경 사항이 포함되어 있습니다. 이러한 변경 사항은 React 19의 개선 사항을 적용하는 데 필요하며, 가이드라인을 따르는 라이브러리는 손상시키지 않습니다.

Versioning Policy에 따라 이러한 업데이트는 중요한 변경 사항으로 분류되지 않으며, 업그레이드 방법에 대한 문서도 포함되지 않습니다. internals에 의존하는 모든 코드를 제거할 것을 권장합니다.

internals 사용의 영향을 반영하기 위해 SECRET_INTERNALS 접미사의 이름을 다음과 같이 변경했습니다:

_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE

앞으로는 React에서 internals에 대한 접근을 보다 적극적으로 차단하여 사용을 억제하고 사용자의 업그레이드가 차단되지 않도록 할 것입니다.

TypeScript changes

Removed deprecated TypeScript types

우리는 React 19의 제거된 API들을 기반으로하는 TypeScript 타입들을 제거할 예정입니다. 제거된 타입 중 일부는 더 관련성이 높은 패키지로 이동되었고, 다른 유형은 더 이상 React의 동작을 설명하는 데 필요하지 않습니다.

types-react-codemod 을 통해 지원하는 대체 타입들의 리스트를 확인하세요. 만약 codemode가 무언가를 놓친다는 생각이 들면 list of missing React 19 codemods에서 계속해서 추적할 수 있습니다.

ref cleanups required

이 변경 사항은 React 19 codemod 프리셋에 no-implicit-ref-callback-return으로 포함되어 있습니다.

ref 클린업 함수의 등장으로, ref callback 함수에서 어떤 무언가를 리턴하는 행위는 TypeScript에 의해 거절(rejected)됩니다. 이를 고칠 수 있는 방법은 implicit returns 사용을 피하는 것입니다.

- <div ref={current => (instance = current)} />
+ <div ref={current => {instance = current}} />

기존의 코드는 HTMLDivElement의 인스턴스를 리턴하고 TypeScript는 이것이 클린업 함수인지 아닌지 알 수 없습니다.

useRef requires an argument

이 변경 사항은 React 19 codemod 프리셋에 refobject-defaults으로 포함되어 있습니다.

TypeScript와 React의 작동 방식에 대한 오랜 불만 중 하나가 useRef였습니다. 이제 useRef에 인수가 필요하도록 유형을 변경했습니다. 이렇게 하면 type signature이 상당히 단순해집니다. 이제 createContext처럼 동작합니다.

// @ts-expect-error: Expected 1 argument but saw none
useRef();
// Passes
useRef(undefined);
// @ts-expect-error: Expected 1 argument but saw none
createContext();
// Passes
createContext(undefined);

이것은 모든 refs가 mutable하다는 것을 의미하기도 합니다. 당신은 더 이상 ref를 null로 초기화하면서 발생하는 ref를 mutate할 수 없는 이슈를 마주하지 않을 것입니다.

const ref = useRef<number>(null);

// Cannot assign to 'current' because it is a read-only property
ref.current = 1;

MutableRefuseRef 가 항상 리턴하는 단일 RefObject 타입에 대한 선호에 따라 depreacted될 예정입니다.

interface RefObject<T> {
  current: T
}

declare function useRef<T>: RefObject<T>

useRef에는 여전히 RefObject<T | null>을 자동으로 반환하는 useRef<T>(null)에 대한 편의성 오버로드(convenience overload)가 있습니다. useRef에 필요한 인자로 인한 마이그레이션을 용이하게 하기 위해 RefObject<T | undefined>을 자동으로 반환하는 useRef(undefined)에 대한 편의성 오버로드가 추가되었습니다.

이 변경 사항에 대한 이전 논의를 살펴보려면 [RFC] Make all refs mutable을 보십시오.

Changes to the ReactElement TypeScript type

이 변경사항은 react-element-default-any-props codemod에 포함되어 있습니다.

ReactElement로 타입이 지정되어있다면 React elements의 props는 element가 이제 any가 아니라 unknown입니다. 만약 ReactElement에 타입을 지정해주었다면 이 변경사항은 영향을 미치지 않습니다.

type Example2 = ReactElement<{ id: string }>["props"];
//   ^? { id: string }

하지만 타입을 지정해주지 않았다면, 당신은 이제 unknown 타입을 핸들링해야 합니다.

type Example = ReactElement["props"];
//   ^? Before, was 'any', now 'unknown'

element props의 불건전한(unsound) 접근에 의존하는 레거시 코드가 많은 경우에만 이 기능이 필요합니다. Element introspection은 escape hatch로만 존재하며, 명시적인 any를 통해 element props가 불건전하다는 것을 명시해야 합니다.

The JSX namespace in TypeScript

이 변경사항은 React 19 codemod 프리셋에 scoped-jsx 으로 포함되어 있습니다.

오랫동안 React.JSX를 위해 타입에서 글로벌 JSX 네임스페이스를 제거하자는 요청 사항이 있었습니다. 이렇게 하면 글로벌 타입의 오염을 방지하여 JSX를 활용하는 여러 UI 라이브러리 간의 충돌을 방지할 수 있습니다.

이제는 declare module "..." 안에 JSX 네임스페이스의 모듈 보강을 작성할 필요가 있습니다.

// global.d.ts
+ declare module "react" {
    namespace JSX {
      interface IntrinsicElements {
        "my-element": {
          myElementProps: string;
        };
      }
    }
+ }

정확한 module specifier는 당신이 tsconfig.json 에 작성한 compilerOptions 에 명시된 JSX 런타임에 의해 결정됩니다.

  • For "jsx": "react-jsx" it would be react/jsx-runtime.
  • For "jsx": "react-jsxdev" it would be react/jsx-dev-runtime.
  • For "jsx": "react" and "jsx": "preserve" it would be react.

Better useReducer typings

useReducer 는 이제 개선된 타입 인터페이스를 갖습니다. (thanks to @mfp22)

그러나 이를 위해서는 useReducer가 전체 reducer type을 type parameter로 받아들이지 않고 대신 아무것도 필요하지 않거나(컨텍스트 타입에 의존) 상태 타입과 액션 타입을 모두 필요로 하는 획기적인 변경이 필요했습니다.

새로운 best practice는 useReducer 에 type arguments를 전달하지 않는 것입니다.

- useReducer<React.Reducer<State, Action>>(reducer)
+ useReducer(reducer)

이것은 아마 당신이 명시적으로 상태와 액션에 대한 타입(Action을 튜플 형태로 타입 명시)을 지정한 엣지 케이스에서는 동작하지 않을 수 있습니다.

- useReducer<React.Reducer<State, Action>>(reducer)
+ useReducer<State, [Action]>(reducer)

만약 당신이 reducer를 인라인으로 정의했다면, 대신 함수 매개 변수에 주석을 달 것을 권장합니다.

→ we encourage to annotate the function parameters instead

→ 매개 변수에 직접 타입을 지정하는 것을 의미하는 것 같습니다.

- useReducer<React.Reducer<State, Action>>((state, action) => state)
+ useReducer((state: State, action: Action) => state)

그리고 아래는 useReducer 밖에 reducer를 옮기고 싶을 때 작성해야 하는 방식입니다.

const reducer = (state: State, action: Action) => state;

Changelog

Other breaking changes

  • react-dom: Error for javascript URLs in src/href #26507
  • react-dom: Remove errorInfo.digest from onRecoverableError #28222
  • react-dom: Remove unstable_flushControlled #26397
  • react-dom: Remove unstable_createEventHandle #28271
  • react-dom: Remove unstable_renderSubtreeIntoContainer #28271
  • react-dom: Remove unstable_runWithPrioirty #28271
  • react-is: Remove deprecated methods from react-is 28224

Other notable changes

  • react: Batch sync, default and continuous lanes #25700
  • react: Don’t prerender siblings of suspended component #26380
  • react: Detect infinite update loops caused by render phase updates #26625
  • react-dom: Transitions in popstate are now synchronous #26025
  • react-dom: Remove layout effect warning during SSR #26395
  • react-dom: Warn and don’t set empty string for src/href (except anchor tags) #28124

우리는 React 19 출시와 함께 모든 changelog를 publish할 예정입니다.


이 포스트를 리뷰해주고 수정해주신 Andrew Clark, Eli White, Jack Pope, Jan Kassens, Josh Story, Matt Carroll, Noah Lemen, Sophie Alpert, 그리고 Sebastian Silbermann에게 감사를 전합니다.