概要
React×TypeScriptで、フォーム画面から画像などのファイルをPOSTする方法をご紹介します。
React×TypeScriptの組み合わせでの記事があまりなかったので書きます。
本当はカスタムフックやserviceファイルを作ってコンポーネント内にロジックを書かないようにしているのですが、今回は便宜上、コンポーネントファイル内で完結させております。
前提条件
TypeScript 3.7.2
React 16.12.0
実装したコード
まずはフォームから。
必要な部分のみ抜粋してます。
<div>
<form>
<label htmlFor="img">画像</label>
<input id="img" type="file" accept="image/*,.png,.jpg,.jpeg,.gif" onChange={getImage}>
<input type="button" value="保存" onClick={submitImage} >
</form>
</div>
画像が選択されると、onChangeイベントが発火し、getImageメソッドを、
保存ボタンがクリックされるとsubmitImageメソッドを実行するようにします。
メソッドの処理の詳細は以下。
const [image, setImage] = useState<File>()
const getImage = (e: React.ChangeEvent<HTMLInputElement>) => {
if(!e.target.files) return
const img: File = e.target.files[0]
setImage(img)
}
const submitImage = () => {
const header = { headers: {
'Content-Type': 'application/json;charset=UTF-8',
"Access-Control-Allow-Origin": "*",
}}
const data = new FormData()
data.append('file', image)
const postImageUri = '任意のURL'
axios.post(postImageUri, data, header)
.then(res => {
//任意の処理
}).catch(err => {
//任意の処理
})
}
ちなみにgetImageの引数eに設定している型は、VSCodeでeにカーソルを合わせると出てくるウィンドウに表示されている型をそのまま使ってます。
2行目で、画像が選択されていない場合は、何もせずreturnさせてます。
選択されている場合は、e.target.files[0]で画像を取得して、setImage(img)でstateの値を更新しております。
submit時は、stateの値をaxiosでpostするようにしてます。
パラメータにはFormDataインターフェイスを使用し、appendで要素を追加するようにしております
(なのでファイル以外もあればappendで追加すれば良いかと思います)
まとめ
VueからReactに移行したがVueの方が書きやすかったな〜というのが今の心情です。
また詰まる箇所があれば随時アウトプットしていきます。