React19 RC アップグレードガイドをまとめてみた

# はじめに
ささっとドキュメントを読んだので自分用にまとめました。
誤字や間違っているところあったらコメントで教えてくださいませ:relaxed:

## 1. インストール

### npm/yarnでのインストール
```bash
npm install --save-exact react@rc react-dom@rc
# または
yarn add --exact react@rc react-dom@rc
```
- 注意: `@rc`タグを使用して、リリース候補版をインストールします。

### TypeScriptユーザー向け
package.jsonに以下を追加:
```json
{
  "dependencies": {
    "@types/react": "npm:types-react@rc",
    "@types/react-dom": "npm:types-react-dom@rc"
  },
  "overrides": {
    "@types/react": "npm:types-react@rc",
    "@types/react-dom": "npm:types-react-dom@rc"
  }
}
```
- 理由: 正式リリース前は通常の@types/reactパッケージではなく、専用のパッケージを使用します。

## 2. 破壊的変更

### レンダー中のエラー処理
- 変更点: エラーが再スローされなくなりました。
- 対応:
  - キャッチされないエラー: `window.reportError`に報告
  - キャッチされたエラー: `console.error`に報告
- 新しいエラー処理オプション:
```javascript
const root = createRoot(container, {
  onUncaughtError: (error, errorInfo) => {
    // エラーレポートのログ
  },
  onCaughtError: (error, errorInfo) => {
    // エラーレポートのログ
  }
});
```

### 非推奨APIの削除
1. propTypes と defaultProps（関数コンポーネント）
   - 代替: TypeScriptまたはES6デフォルトパラメータを使用
   ```typescript
   interface Props {
     text?: string;
   }
   function Heading({text = 'Hello, world!'}: Props) {
     return <h1>{text}</h1>;
   }
   ```
   <br>
2. contextTypes と getChildContext
   - 代替: React.createContextとuseContext
   ```javascript
   const FooContext = React.createContext();
   function Parent() {
     return (
       <FooContext.Provider value='bar'>
         <Child />
       </FooContext.Provider>
     );
   }
   ```
<br>
3. 文字列形式のref
   - 代替: コールバック形式のrefまたはuseRef

   ```javascript
   function MyComponent() {
     const inputRef = useRef(null);
     useEffect(() => {
       inputRef.current.focus();
     }, []);
     return <input ref={inputRef} />;
   }
   ```
   
<br>
4. ReactDOM.render, ReactDOM.hydrate
   - 代替: createRoot, hydrateRoot
   
   ```javascript
   import {createRoot} from 'react-dom/client';
   const root = createRoot(document.getElementById('root'));
   root.render(<App />);
   ```

## 3. 新たな非推奨化

### element.ref
- 代替: `element.props.ref`を使用

### react-test-renderer
- 推奨: @testing-library/reactまたは@testing-library/react-nativeに移行

## 4. 注目すべき変更点

### StrictMode
- useMemoとuseCallbackの挙動変更: 開発中の二重レンダー時に1回目の結果を再利用

### UMDビルドの削除
- 代替: ESMベースのCDNを使用
```html
<script type="module">
  import React from "https://esm.sh/react@19/?dev"
  import ReactDOMClient from "https://esm.sh/react-dom@19/client?dev"
  // ...
</script>
```

### Reactの内部構造依存
- `SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED`などの内部APIに依存するコードは動作しなくなる可能性があるらしい....

## 5. TypeScript関連の変更

### useRefの引数必須化
```typescript
// エラー
useRef();
// OK
useRef(undefined);
```

### ReactElement型の変更
- propsのデフォルト型が`any`から`unknown`に変更

### JSX名前空間の変更
- グローバルJSX名前空間からReact.JSXに移行
```typescript
declare module "react" {
  namespace JSX {
    // カスタム定義
  }
}
```

## 6. codemodの活用

全体的な移行:
```bash
npx codemod@latest react/19/migration-recipe
```

個別の変更:
- ReactDOM.renderの置換: `npx codemod@latest react/19/replace-reactdom-render`
- 文字列refの置換: `npx codemod@latest react/19/replace-string-ref`
- propTypesからTypeScriptへの変換: `npx codemod@latest react/prop-types-typescript`

## 7. その他の重要な変更

- サスペンスの挙動改善
- レンダーフェーズでの無限ループ検出
- SSR中のレイアウトエフェクト警告削除

## まとめ

とりあえず大まかな箇所だけまとめておりますので、参考になればと思います！
以下、アップグレードガイドです。

https://ja.react.dev/blog/2024/04/25/react-19

**React19を一言で表すなら「Actionsの時代」といったところでしょうか**

フロントエンドは移り変わりが早すぎるので乗り遅れずにキャッチアップしていきましょう:point_up: