どうも、駆け出し12冠エンジニアのアスカです。Amplify Gen2がGAしてドキュメントのStorage機能に関する部分が充実していたので、それを参考にしながら触ってみます!
Amplify Gen2のドキュメント
想像以上にボリュームがあるので、連載の形をとっています。今回はアップロードとダウンロードの機能を触っていきたいと思います。
参考:
Amplify Gen2のStorage機能を使ってみた-①最初のアップロードまで-
アップロード
Storage Manager React UI Componentを使う
まず以下のコマンドでライブラリをインポートします。
npm add @aws-amplify/ui-react-storage aws-amplify
早速Reactを書いて実装してみます。
アップロードボタンのコンポーネントを作成します。
import { StorageManager } from '@aws-amplify/ui-react-storage';
import '@aws-amplify/ui-react/styles.css';
export const DefaultStorageManagerExample = () => {
return (
<StorageManager
acceptedFileTypes={['image/*']}
path="public/"
maxFileCount={1}
isResumable
/>
);
};
このボタンをメイン部分にインポートします。
import { Authenticator } from '@aws-amplify/ui-react'
import '@aws-amplify/ui-react/styles.css'
import {DefaultStorageManagerExample } from '../src/components/Elements/Buttons/uploadbutton';
function App() {
return (
<Authenticator>
{({ signOut, user }) => (
<main>
<h1> Welcome to {user?.signInDetails?.loginId}</h1>
<button onClick={signOut}>Sign out</button>
<DefaultStorageManagerExample/>
</main>
)}
</Authenticator>
);
}
export default App;
これでボタンは生成されますが、ストレージのパスに許可を与えないとアップロードに失敗します。
ここでは以下のようにamplify/storage/resource.tsを編集します。
import { defineStorage } from '@aws-amplify/backend';
export const storage = defineStorage({
name: 'amplifygen2Test',
access: (allow) => ({
'public/*': [
allow.authenticated.to(['read','write']),
allow.guest.to(['read'])
],
})
});
これでストレージ配下のpublic/にログイン済みのユーザがファイルをアップロード出来るようになりました。
カスタムは色々可能で、詳細は下記ドキュメントにあります。
Amplify Dev Center
多くのPropsが用意されていてカスタマイズ性が高そうです。
例えば、processFile?にファイルを処理する関数を入れると、アップロード時に処理が走ります。
displayText Propsを使えばUIの表示文字の変更も可能ですし、各種オーバーライドも可能でデザインも自由度高く変更出来そうです。今回は表示文字を日本語に変えてみます。
import { StorageManager } from '@aws-amplify/ui-react-storage';
import '@aws-amplify/ui-react/styles.css';
export const DefaultStorageManagerExample = () => {
return (
<StorageManager
acceptedFileTypes={['image/*']}
path="public/"
maxFileCount={1}
isResumable
+ displayText={{
+ // some text are plain strings
+ dropFilesText: 'ドラッグ&ドロップ',
+ browseFilesText: 'ファイルを選択する',
+ uploadSuccessfulText: 'アップロード完了',
+ // others are functions that take an argument
+ getFilesUploadedText(count) {
+ return `${count}枚 画像がアップロードされました`;
+ },
+ }}
/>
);
};
簡単に表示を日本語にする事が出来ました。
要件に応じてまだまだ出来る事はあるので、これからも利用していきたいです。
リスト
ドキュメントにはlist関数の使用方法が記載されています。これを利用して簡単なリストコンポーネントを実装してみます。
import React, { useState, useEffect } from 'react';
import { list } from 'aws-amplify/storage';
const FileList = () => {
const [files, setFiles] = useState([]);
const [error, setError] = useState(null);
useEffect(() => {
const fetchFiles = async () => {
try {
const result = await list({
path: 'public/'
});
setFiles(result.items);
} catch (err) {
console.error(err);
setError(err.message);
}
};
fetchFiles();
}, []);
return (
<div>
<h1>File List</h1>
{error && <p>Error fetching files: {error}</p>}
<ul>
{files.map((file, index) => (
<li key={index}>
{file.path} - Last modified: {new Date(file.lastModified).toLocaleString()}
</li>
))}
</ul>
</div>
);
};
export default FileList;
fetchFiles 関数でS3内のpublic/配下のファイルリストを取得してこれを並べて表示します。ここではpathと最終編集日時を表示していますが、それ以外にもsizeやnextTokenといったプロパティがあります。
上記のコードで定義したFileListをApp.tsxに実装してみます。
import { Authenticator } from '@aws-amplify/ui-react'
import '@aws-amplify/ui-react/styles.css'
import { useEffect, useState } from "react";
import type { Schema } from "../amplify/data/resource";
import { generateClient } from "aws-amplify/data";
import { uploadData } from 'aws-amplify/storage';
import {DefaultStorageManagerExample } from '../src/components/Elements/Buttons/uploadbutton';
+ import FileList from '../src/components/Elements/Lists/list_test'
const client = generateClient<Schema>();
function App() {
const [todos, setTodos] = useState<Array<Schema["Todo"]["type"]>>([]);
useEffect(() => {
const [file, setFile] = useState<File | undefined>();
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const files = event.target.files;
if (files) {
setFile(files[0]);
}
};
const handleUpload = () => {
if (file) { // file が undefined でないことを確認
uploadData({
path: `picture-submissions/${file.name}`,
data: file,
})
alert(`${file.name}がアップロードされました。`)
} else{
alert(`ファイルが選択されていません。`)
};
};
return (
<Authenticator>
{({ signOut, user }) => (
<main>
<h1> Welcome to {user?.signInDetails?.loginId}</h1>
<button onClick={signOut}>Sign out</button>
<DefaultStorageManagerExample/>
+ <FileList/>
</main>
)}
</Authenticator>
);
}
export default App;
public/にアップロードしたファイルパスをリストする事が出来ました。
これで画像の表示やダウンロードに繋げる事が出来ます。
まとめ
この記事ではドキュメントをベースに画像のアップロードとリストを実装してみました。
リストに関してはドキュメント上にsampleのコンポーネントは無かったので、この記事が少しでも初心者仲間のが参考になれば嬉しいです。次はダウンロードや削除機能を試していきます。