20.1 XSS
Reactは文字列を通常エスケープするが、次は注意する。
dangerouslySetInnerHTML- 信頼できないURL
- Markdown・HTMLレンダラー
- DOMを直接扱う外部ライブラリ
- サーバーから返るスクリプト可能なデータ
サニタイズは信頼境界で実施し、許可リスト方式を検討する。
20.2 認証と認可
クライアント側の表示制御はセキュリティ境界ではない。
{user.role === "admin" && <AdminButton />}
この表示制御に加え、サーバー側で必ず認可する。
20.3 Server Functionsの防御
"use server";
export async function deleteUser(userId: string) {
const actor = await requireAuthenticatedUser();
if (!actor.permissions.includes("user:delete")) {
throw new Error("Forbidden");
}
const parsedId = userIdSchema.parse(userId);
await db.user.delete({
where: { id: parsedId },
});
}
クライアントから渡される引数、隠しフィールド、cookie、ヘッダーを無条件に信用しない。
20.4 依存関係管理
- Reactとフレームワークのセキュリティ告知を追う
- lockfileを管理する
- 自動更新PRを利用する
- 更新をテスト環境で検証する
- RSC関連パッケージを最新修正版へ更新する
- 脆弱な一時パッチ版に留まらない
2025年末から2026年初頭にはRSC関連パッケージで重大な脆弱性と追加修正が公表された。RSC採用プロジェクトは、書籍や固定記事のバージョン番号ではなく、常に最新の公式アドバイザリを確認する。
20.5 シークレット
クライアントbundleに含まれる環境変数は秘密ではない。
- DB接続情報
- API秘密鍵
- サービスアカウント
- 署名鍵
これらはサーバー側だけで使用する。VITE_や公開用プレフィックス付き変数はブラウザから閲覧される前提で扱う。
20.6 エラー監視
最低限記録する。
- エラー本体
- stack trace
- リリース番号
- ルート
- ユーザー操作の文脈
- request ID
- Server/Client区分
- ブラウザ・端末
- 個人情報を除去した入力概要
Error Boundaryだけでは、イベントやサーバーエラーを全て捕捉できない。層ごとの監視が必要。
20.7 React 18から19への移行
推奨手順:
- 18.3へ更新し警告を確認
- 非推奨APIを除去
- 新しいJSX Transformを確認
reactとreact-domを19へ更新- TypeScript型を更新
- テストを更新
- SSR・hydrationを確認
- Strict Modeで再検証
- 段階的に新機能を導入
20.8 主な変更
旧ルートAPI
// 旧式
ReactDOM.render(<App />, container);
// 現行
createRoot(container).render(<App />);
ref
// 既存コード
const Input = forwardRef<HTMLInputElement, Props>(
function Input(props, ref) {
return <input ref={ref} {...props} />;
}
);
// React 19の新規コード
function Input({
ref,
...props
}: Props & { ref?: React.Ref<HTMLInputElement> }) {
return <input ref={ref} {...props} />;
}
Context Provider
// 旧来
<ThemeContext.Provider value={theme}>
<App />
</ThemeContext.Provider>
// React 19
<ThemeContext value={theme}>
<App />
</ThemeContext>
20.9 Create React Appからの移行
候補:
- Vite
- Next.js
- React Router Framework Mode
- その他の対応フレームワーク
移行時の確認:
- 環境変数プレフィックス
publicディレクトリ- SVG import
- CSS Modules
- Jest設定
- proxy
- service worker
- absolute import
- Node.js polyfill
- 本番ビルド出力
20.10 クラスコンポーネント
新規コードは関数コンポーネントとHooksが基本だが、次の理由で理解は必要である。
- 既存資産
- Error Boundary
- 古いライブラリ
- 移行作業
対応関係を機械的に覚えるより、Effectの同期モデルとstate設計を改めて考える。
| クラス | 関数コンポーネント |
|---|---|
this.state |
useState / useReducer |
componentDidMount |
用途に応じたuseEffect |
componentDidUpdate |
依存関係付きEffect |
componentWillUnmount |
Effect cleanup |
shouldComponentUpdate |
Compiler / memo |
createRef |
useRef |