読者です 読者をやめる 読者になる 読者になる

望月いちろうのREADME.md

書き溜めておいた技術記事や旅行記のバックアップです。

Reactでajaxを利用する - 画像や動画などのフォームデータをアップロードしたり非同期でデータを取得する

f:id:mochizuki_p:20161029101755p:plain

jQueryを利用するのはアンチパターン

どうせReactを使うのなら完全にjQueryなしでアプリを作ってみたくはありませんか?

僕はjQueryなしでやってみたいです。

ユーザビリティを考えるとデータの転送量も減らしたいですし。

でも個人的に困っていたのはajaxの取り扱いでこれを純粋なJSに置き換えるのは面倒臭い

そこでsuperagentを利用しよう

SuperAgent — elegant API for AJAX in Node and browsers

superagentとはReact用のajaxライブラリ、get,post,put,deleteなどの主要なリクエスト形式をカバーしています。

非常にシンプルな見た目で、コードの記述量も大幅に減らすことができます。コールバック形式になっているので、Node.jsに慣れていれば、返り値の処理も非常に分かりやすくなっています。

使い方

npmでインストールする

sudo npm install superagent --save

Reactに組み込む

import request from "superagent";

実際にアクセスを行う

インスタンスから各メソッドを利用する。各メソッドには基本的にURLを引数とする。

リスポンスはend()内のコールバックで処理を行う。このとき、エラー時の対応も設定できる。

GET

// www.example.comにGETリクエストを送る
request.get("http://www.example.com").end(function(err, res){
 
  if(err){
   //ここでエラー処理を行う
    return false;
  }
  this.hoge(res) //リスポンスに対して適切な処理を行うhoge関数に返り値を渡す。 
})

POST

// www.example.com/userに対して{"name":"mochizuki","service":"hotel"}というJSONデータを送信する
  request.post('http://www.example.com/user')
    .set('Content-Type', 'application/json')
    .send({"name":"mochizuki","service":"hotel"})
    .end(function(err, res){
 
  if(err){
   //ここでエラー処理を行う
    return false;
  }
  this.hoge(res) //リスポンスに対して適切な処理を行うhoge関数に返り値を渡す。 
})
画像や動画をアップロード
multipart/form-data

POSTで頻繁に使用されるのは、各入力欄やテキストファイル、画像・動画といったバイナリデータを含む複数の形式のファイルを、ひとまとめにして送信するmultipart/form-data形式のリクエストです。

これについては少しコツがいります

一般的にReactでDOMから直接getElementByIdを利用して値を取得するのはアンチパターンです。

そのため、ドラッグアンドドロップやinputの変更イベントから、データを取得してフォームデータのインスタンスに格納していくのがベストでしょう。

フォームデータのインスタンス

var formData = new FormData();

このフォームデータに値を格納

// keyにデータ名、valueにデータ本体を指定
formData.append('key', 'value');

フォームへの入力値の変更イベントを取得するにはコンポーネントのrender関数内のinputでonChangeを設定します。

<input type="file" ref="file" onChange={this.onChangeFile} />

このイベントから入力されたファイルを取得するにはe.target.filesを参照する

onChangeFile: function(e) {
        var files = e.target.files;
 }

そして先ほど確保したフォームデータに格納していきましょう

for (var key in files) { 
   if (files.hasOwnProperty(key) && files[key]) { 
      formData.append(key, files[key]); 
   } 
}

最後にこのフォームデータをsendにセットしてリクエストを実行します。

request
.post("http://www.example.com/image")
.send(formData)
.end(function(err, res){
 
  if(err){
   //ここでエラー処理を行う
    return false;
  }
  this.hoge(res) //リスポンスに対して適切な処理を行うhoge関数に返り値を渡す。 
})

これで画像などのデータを送信できますね。

WebデベロッパーのためのReact開発入門 JavaScript UIライブラリの基本と活用

WebデベロッパーのためのReact開発入門 JavaScript UIライブラリの基本と活用