使用シナリオ
Ant Design Proフォームにおける編集機能でのファイル表示実装
ReactベースのAnt Design Proアプリケーションを開発する際、フォームにファイルアップロード機能を統合することが頻繁にあります。Ant Design ProはProFormUploadButtonとUploadコンポーネントを提供しており、これらはファイルと画像のアップロードを処理する強力なツールです。しかし、一般的な課題は編集モードで、以前にアップロードしたファイルURLをどのようにして適切に表示し、ユーザーが追加済みのファイルや画像を直感的に確認して修正できるようにするかという点です。
目標機能
本記事では、ProFormUploadButtonとUploadコンポーネントを使用したフォームにおいて、編集シナリオで自動的に以前にアップロードしたファイルURLをロードして表示する方法について詳しく説明します。この機能はユーザーエクスペリエンスを向上させ、編集プロセスを簡素化する上で極めて重要です。
実装手順
ProFormUploadButton
1. コンポーネント属性の設定
<ProFormUploadButton
name="document"
max={1}
rules={[{ required: true, message: 'ドキュメントをアップロードしてください' }]}
accept={
(
formRef.current?.getFieldValue('materialTypeId')
? formRef.current?.getFieldValue('materialTypeId') == 2
: current?.materialTypeId == 2
)
? 'video/*'
: '.ppt,.pptx'
}
tooltip={isNewEntry === 'add' ? '' : '変更する場合は、再度アップロードしてください!'}
fieldProps={{
// アップロード進捗バー
progress: {
strokeColor: {
'0%': '#f56a00',
'100%': '#722ed1'
},
strokeWidth: 3,
format: (percent) => percent && `${parseFloat(percent.toFixed(2))}%`,
},
// カスタムアップロードAPI
customRequest: async (options: any) => {
const formData = new FormData();
formData.append('file', options.file);
formData.append('category', "1");// 1はドキュメント
try {
const { success, data } = await fileUploadService(formData);
if (success) {
options.onSuccess(options.file);
setFileStorageUrl(data);
return success;
} else {
message.error('アップロードに失敗しました。ページを更新して再試行してください');
return false;
}
} catch (error) {
message.error('アップロードに失敗しました。ページを更新して再試行してください');
return false;
}
},
// プレビュー機能の実装
onPreview: (file: any) => { window.open(file?.url, '_blank') }
}}
/>
2. コンポーネントの表示値設定
useEffect(()=>{
// FormコンポーネントのformRefを使用して初期値を設定
formRef?.current?.setFieldsValue({
document:[
{
url: selectedRecord?.fileUrl,
uid: '-1',
name: selectedRecord?.title,
// サムネイル画像の設定
thumbUrl: require("../../../../../../public/assets/images/default-thumbnail.png")
}
]
})
},[selectedRecord])
Uploadコンポーネント
1. コンポーネント属性の設定
// 1. ページレイアウト
<Col span={8}>
// ProFormSwitchでUploadコンポーネントの表示を制御
<ProFormSwitch
name="showOnHomepage"
label="ホームページに表示"
fieldProps={{
checkedChildren: "表示する",
unCheckedChildren: "表示しない",
defaultChecked: false,
onChange: () => {
setUploadedFiles([])
}
}}
/>
</Col>
<Col span={8}>
// ProFormDependencyでフォーム項目間の依存関係を実装
<ProFormDependency name={['showOnHomepage']}>
{({ showOnHomepage }) => {
return showOnHomepage ?
<Row>
<Col span={1} />
<Col span={11}>ホームページ画像:</Col>
<Col span={12}>
<Upload
{...uploadConfig}// アップロード属性の設定
name="homepageImage"
maxCount={1}
listType="picture-card"
fileList={uploadedFiles}// 表示リストの設定
onChange={handleFileChange}
onPreview={handlePreview}
>
// アップロードボタンのテキスト
{uploadedFiles.length < 1 && '+ クリックしてアップロード'}
</Upload>
</Col>
</Row> : ''
}}
</ProFormDependency>
</Col>
// 2. 関数部分
// アップロード属性
const uploadConfig = {
accept: '.jpg,.jpeg.,.png',
customRequest: async (options: any) => {
const formData = new FormData();
formData.append('file', options.file);
try {
const { success, data } = await homepageImageUpload(formData);
if (success) {
options.onSuccess(options.file);
setHomepageImageUrl(data);
return success;
} else {
message.error('アップロードに失敗しました。ページを更新して再試行してください');
return false;
}
} catch (error) {
message.error('アップロードに失敗しました。ページを更新して再試行してください');
return false;
}
},
onPreview: () => { }
}
const handleFileChange = (response: any) => {
setUploadedFiles(response?.fileList?.map((item: any) => (
{ ...item, url:item.response?.data?.fileUrl })));
};
2. コンポーネントの表示値設定
// カスタム関数、setUploadedFiles()の非同期問題を解決するために使用
const setFileListForDisplay = (imageUrl: any) => {
setUploadedFiles([
{
url: imageBaseUrl + `${imageUrl}`,
uid: '-1',
name: 'homepage-image.png',
}
])
}