React Auto Key Plugin
transition()呼び出し時にkeyを自動生成するビルドプラグイン
概要
@ssgoi/reactのAuto Key Pluginは、transition()関数呼び出し時に一意のkeyを自動生成するビルドタイムプラグインです。
なぜkeyが必要か?
SSGOIは要素のアニメーション状態を追跡するために一意のkeyが必要です。keyがないと:
- 同じトランジションを使用する要素を区別できない
- ページ遷移後にアニメーション状態が維持されない
- 要素のマウント/アンマウント時に予期しない動作が発生
プラグインの役割
ビルド時にすべてのtransition()呼び出しを分析し、ファイル名:行:列に基づいた一意のkeyを自動注入します。
// 作成したコード
<div ref={transition(fade())}>Content</div>
// ビルド後の変換されたコード
<div ref={transition({ ...fade(), key: "page.tsx:15:6" })}>Content</div>
インストールと設定
プラグインは@ssgoi/reactパッケージに含まれています。別途インストールは不要です。
Next.js (Webpack)
// next.config.ts
import type { NextConfig } from "next";
import SsgoiAutoKey from "@ssgoi/react/unplugin/webpack";
const nextConfig: NextConfig = {
webpack: (config) => {
config.plugins.push(SsgoiAutoKey());
return config;
},
};
export default nextConfig;
Vite
// vite.config.ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import SsgoiAutoKey from "@ssgoi/react/unplugin/vite";
export default defineConfig({
plugins: [react(), SsgoiAutoKey()],
});
Rollup
// rollup.config.js
import SsgoiAutoKey from "@ssgoi/react/unplugin/rollup";
export default {
plugins: [SsgoiAutoKey()],
};
esbuild
import SsgoiAutoKey from "@ssgoi/react/unplugin/esbuild";
await esbuild.build({
plugins: [SsgoiAutoKey()],
});
使用方法
基本的な使い方(プラグインあり)
プラグインが設定されている場合、keyを省略できます。
import { transition } from '@ssgoi/react';
import { fade, scale } from '@ssgoi/react/transitions';
function MyComponent() {
return (
<>
{/* keyを省略可能 - 自動生成されます */}
<div ref={transition(fade())}>
Fade効果
</div>
<div ref={transition(scale())}>
Scale効果
</div>
</>
);
}
明示的なkey
必要に応じて明示的にkeyを指定できます。プラグインは既にkeyがある場合はスキップします。
<div ref={transition({
key: "my-custom-key", // 明示的なkey
...fade()
})}>
Content
</div>
リストでの使用(.map)
.map()でレンダリングされるリストでは、JSX keyだけで十分です。プラグインがJSX keyを読み取り、ファイル名:行:列:${jsxKey}形式で自動生成します。
function ItemList({ items }) {
return (
<ul>
{items.map((item) => (
<li
key={item.id} // JSX keyだけで十分!
ref={transition(fade())} // プラグインが自動処理
>
{item.name}
</li>
))}
</ul>
);
}
生成されるkeyの例:ItemList.tsx:8:10:item-1、ItemList.tsx:8:10:item-2、...
プラグインなしで使用
プラグインを使用しない場合、一意のkeyを手動で指定する必要があります。
// プラグインなし - keyは必須!
<div ref={transition({
key: "unique-key-1",
...fade()
})}>
Content
</div>
// リストでもkeyが必要
{items.map((item) => (
<li
key={item.id}
ref={transition({
key: `item-${item.id}`, // transition keyも必要
...fade()
})}
>
{item.name}
</li>
))}
動作原理
1. コード分析
プラグインは.tsx、.jsxファイルでtransition()関数呼び出しを検索します。
2. 位置ベースのkey生成
ソースコードの位置(ファイル名、行、列)に基づいて一意のkeyを生成します。
ファイル名:行:列
例:MyComponent.tsx:25:8
3. JSX keyの結合(リスト)
.map()内の要素の場合、親JSX要素のkeyプロップを見つけて結合します。
ファイル名:行:列:${jsxKey}
例:ItemList.tsx:8:10:item-123
4. コード変換
元のコードを変換してkeyを注入します。
// Before
transition(fade())
// After
transition({ ...fade(), key: "MyComponent.tsx:25:8" })
プラグインオプション
interface SsgoiAutoKeyOptions {
/**
* 処理するファイル拡張子
* @default ['.tsx', '.jsx']
*/
include?: string[];
/**
* 除外するファイルパターン
* @default [/node_modules/]
*/
exclude?: (string | RegExp)[];
}
使用例
// next.config.ts
import SsgoiAutoKey from "@ssgoi/react/unplugin/webpack";
const nextConfig = {
webpack: (config) => {
config.plugins.push(SsgoiAutoKey({
include: ['.tsx'], // .tsxファイルのみ
exclude: [/node_modules/, /\.test\.tsx$/], // テストファイルを除外
}));
return config;
},
};
注意事項
このプラグインはReact専用です。Svelte、Vue、Angularなど他のフレームワークでは使用できません。
条件付きレンダリングに注意:同じ位置で条件によって異なる要素がレンダリングされる場合、同じkeyが生成される可能性があります。そのような場合は明示的なkeyを使用してください。
// ⚠️ 注意:同じ位置での条件付きレンダリング
{isLoading
? <div ref={transition(fade())}>Loading...</div> // key: file:10:6
: <div ref={transition(fade())}>Content</div> // key: file:11:6(異なる行なのでOK)
}
// ✅ 同じ行の場合は明示的なkeyを使用
{isLoading
? <div ref={transition({ key: "loading", ...fade() })}>Loading...</div>
: <div ref={transition({ key: "content", ...fade() })}>Content</div>
}
デバッグ
開発中に生成されたkeyを確認するには、ブラウザの開発者ツールでビルドされたコードを確認するか、次のようにログを出力できます:
const myTransition = transition(fade());
console.log(myTransition); // key値を確認