こんにちは、れいじです。
年末なので趣味の開発に時間をつぎ込んでいます。Webサービスを作っているのですが、あまり複雑なシステムではないのでreduxなどは導入せずにシンプルに作っています。
APIとの通信に使用するモジュールとしてはredux-sagaとかredux-thunkとかまぁいろいろあるわけですが、上述の通りreduxは導入しないのでこれらは候補に入りません。
なので最近ナウいと噂のaxiosを使用してAPI通信を実装したいと思います。
やりたいこと
ボタン側
※UIデザインにmaterial-uiを使用しています。そのあたりの記述はうまく読解してもらえればと
<div> <input accept="image/*" multiple type="file" className="input" id="upload-img" onChange={this.uploadFile.bind(this)} /> <label htmlFor="upload-img"> <Button variant="contained" component="span" color="secondary" aria-label="Add" className="uploadIcon"> <CameraIcon /> UPLOAD </Button> </label> </div>
ボタンを押すとファイル選択用ブラウザが開きます。画像を選択した後は、取得した画像をAPIにポストします。
画像を受け付ける部分(uploadFile())
uploadFile(e) { this.setState({ file: e.target.files[0], }, () => { this.sendFile(); }); };
最新の画像をStateに保持・更新した後にAPIに画像を送ります。
画像をAPIに送信する部分(sendFile())
いよいよaxiosが出てくる部分です
sendFile() { // show loading modal this.setState({isLoading: true}); const params = new FormData(); params.append('file', this.state.file); axios .post( 'https://api/upload', params, { headers: { 'content-type': 'multipart/form-data', }, } ) .then((result) => { this.setState({ isLoading: false }); }, ) .catch(() => { console.log('upload failed...'); this.setState({ isLoading: false }); });
axiosでPOST通信をするときのTipsとして、paramsをそのままjson形式で送信すると通信メソッドを.post
で定義していてもOPTIONになってしまいます。
参考:
ここではパラメータをURLSearchParams()
で定義してあげているのですが、今回私はmultipart/form-data
でデータを送りたいので、
const params = new FormData(); params.append('file', this.state.file);
と指定しています。
さらにヘッダーにも
{ headers: { 'content-type': 'multipart/form-data', }, }
をつけてあげます。これでOK。
いいかんじにpostできました。