React 注意事項
この文書では、React 環境で DEXTUploadX5(以下 X5)を使用する際に注意すべき項目のみを整理しています。 問題の多くは、React の再レンダリング特性と X5 の動的生成方式が衝突するときに発生します。
- 再レンダリングのたびに X5 を再生成しないこと
-
X5 は通常の HTML 要素ではなく、内部的に dx5.create によって動的に生成されるコンポーネントです。 そのため、親コンポーネントが再レンダリングされるたびに X5 の生成ロジックが繰り返される構成にしてはいけません。
特に、生成用 useEffect の依存配列に不要な値が入っていると、 再レンダリングのたびに既存インスタンスが破棄され、再ロードされることがあります。
生成ロジックは、実際にインスタンスを再生成する必要がある値にのみ反応するよう制限する必要があります。
DEXTUploadX5UI(List/Tile/Single/Grid) コンポーネントの prop は、React が再レンダリングしても内部 X5 コンポーネントを再ロードしない prop と、再ロードさせる prop に次のように分けられます。
-
X5 コンポーネントを再ロードさせる prop
- id
- type
- progressType
- path
- waitingTime
- lang
-
X5 コンポーネントのロードに影響しない prop
- className
- style
- hidden
- columns
- イベントハンドラー設定に使用する prop
-
- コンポーネント内部にラッピングコンポーネントを宣言する場合
-
X5 React コンポーネントを包む関数コンポーネントを親コンポーネント内部に宣言すると、 親が再レンダリングされるたびに、そのラッピングコンポーネントも新しいコンポーネントとして扱われる可能性があります。
function Sample() { const TestArea = () => { return <DEXTUploadX5List id="x5-01" />; }; return <TestArea />; }この構造では、X5 が繰り返しアンマウント・マウントされる可能性があります。 可能であればラッピングコンポーネントを外に分離するか、メモ化を適用してください。
- 自動ボタンバインディング機能は未対応
-
React 環境では、自動ボタンバインディングが安定して動作しないことがあります。 レンダリングや更新の過程でバインディング時点の内部モジュール参照が変わると、 ボタンイベントは発生しても実際の X5 モジュールオブジェクトが空のままとなり、エラーが発生する場合があります。
X5 React コンポーネントでは、ボタンバインディング用 prop は削除されています。
- 削除イベント内での非同期状態更新タイミングに注意
-
削除関連イベントで React の状態保存関数のコールバック内から 再度 DX5.get(id).getItemById(...) を呼び出すと、 その時点ではすでに項目が削除されており、エラーが発生する可能性があります。
const [eventLog, setEventLog] = useState([]); const handleBeforeItemsDelete = (id, arr) => { // ファイル削除前にイベントログバッファを初期化 setEventLog([]); }; const handleItemDeleting = (id, itemId) => { // 個別削除前に削除対象情報を取得してログに記録 setEventLog(prev => [...prev, `Deleting: ${DX5.get(id)?.getItemById(itemId)?.name}`]); } const handleItemsDeleted = (id, count) => { // 削除完了後に最終ログを記録 setEventLog(prev => [...prev, `Deleted: ${count} files`]); }; <DEXTUploadX5List ... onBeforeItemsDelete={handleBeforeItemsDelete} onItemDeleting={handleItemDeleting} onItemsDeleted={handleItemsDeleted} />このコードでは、「存在しないファイルの一意 ID」に関するエラーが繰り返し発生します。理由は、状態保存関数(`setEventLog`)に渡したコールバックが実行される時点では、対象項目がすでに削除されているため、`getItemById` による再参照が存在しない項目へのアクセスになるからです。
必要な項目情報は状態更新コールバックの中で再取得せず、 イベントが発生した時点で先に変数へ取り出して使用してください。
const handleAItemDeleting = (id, itemId) => { const item = DX5.get(id)?.getItemById(itemId); // 先に抽出 ↰ setEventLog(prev => [...prev, `Deleting: ${item?.name}`]); }; - ref 使用時はロード完了前にアクセスしないこと
-
X5 コンポーネントは非同期でロードされるため、ref が接続されたからといって すぐに内部モジュールを使用できるとは限りません。
条件付きレンダリングを使う場合は、特定のタイミングで ref が再び null になることもあります。 そのため、ロード完了を確認してからアクセスし、一般的には ref でコンポーネントオブジェクトを制御するよりも、onCreated イベント発生後に DX5.get(id) を通じてオブジェクトを取得することを推奨します。
- Grid 列情報は初期適用時に注意
-
Grid スタイルで列情報を prop と onCreated イベントの両方で設定すると、 適用順序によって片方の設定がもう片方を上書きすることがあります。
特に、レンダリング後に実行される効果コードで clearColumns() が呼び出されると、 生成完了イベントで追加した列が再び削除されることがあります。
Grid 列定義は一つの方法で一貫して適用し、 初期生成時点とその後の更新時点を混在させない方が安全です。