konchangakita

KPSを一番楽しんでいたブログ 会社の看板を背負いません 転載はご自由にどうぞ

【Nutanix UUIDエクスプローラーを作ってみよう】React で JavaScript へ挑戦 - fetch編

fetchって言葉は今回実際使ってみるまで、知らなかったのですが(Web初心者丸だし。。。)、Webページ上からFormなどから httpリクエストしてデータをひっぱってくるやつです

【Nutanix UUIDエクスプローラーを作ってみよう】シリーズ
Flask表示までのまとめ
React で JavaScript へ挑戦 - CDN導入編
React で JavaScript へ挑戦 - state編
・React で JavaScript へ挑戦 - fetch編 ←イマココ
React で JavaScript へ挑戦 - filter編

環境の準備

今回までの最終形態はコチラ(Github)で公開しています
<フォルダ構造>


JavaScript に fetch を導入

こんな感じで fetch 関数を呼び出してやることで httpリクエストしてやることができます

const response = await fetch("/api/connect", requestOptions);
// requestOptionsは他で設定する


Form で入力した値を使って httpリクエストする場合には、Form の onSubmit イベントから fetchをおこなう関数を呼び出してやります

<form onSubmit={this.handleConnectPrism} >

Form で受け取った Prism IP、ユーザ名、パスワードの state を使って、httpリクエストする関数はこんな感じ
/flaskr/static/js/test.js

  handleConnectPrism = async(event) => {
    event.preventDefault();
    const requestOptions = {
      method: "POST",
      headers: {'Content-Type' : 'application/json'},
      body: JSON.stringify({
        //Formから取得したデータ
        prism_ip: this.state.prismIp,
        prism_user: this.state.prismUser,
        prism_pass: this.state.prismPass,
      })
    }
    const response = await fetch("/api/connect", requestOptions);
    if (response.ok) {
      let res = await response.json();
      this.setState({
        // リクエスト結果を反映
      });
    }
    else {
      alert("HTTP-Error: " + response.status);
    }

ポイントは、非同期処理を行う async, await を使います
これを使わないと、httpリクエストの結果を待たず処理が進んでしまい、結果表示がおかしくなっちゃいます

state のリフトアップ

では、このfetchの関数をどこに設置するのか?です
React でクラスコンポーネントを使うときは、データの流れを親クラスから子クラスへというの意識する必要があります

今回の場合
1.3-1.FormConnect で、クラスタからデータ取得、Elasticsearchへデータ格納
2.3-2.FormDisplay で、Elasticsearch から表示用データ取得
3.4.List で、取得したデータを表示

この場合、この2つのクラスの親となる 2.Content に、stateをもたせて渡していくことになりますので、fetch関数もココに設置します
Contentクラスに配置させた場合の全体イメージは、こんなこんな感じ

</static/js/test.js>


httpリクエスト先の API作成

まだ現時点では、存在していない httpリクエスト先の 「/api/connect」、「/api/latestdataset」を作っていきます

基本的には Flaskで、API 受け口を作ってやるだけです
あとは以前から作っていたデータ取得の関数をよびだすだけ

from flask import make_response, jsonify

@app.route('/api/connect', methods=['POST'])
def connect():
    data = {}
    print(request.json)
    data['info'], data['cluster_name'] = connect_cluster(request.json)
    return make_response(jsonify(data))

@app.route('/api/latestdataset', methods=['POST'])
def latestdataset():
    cluster_name = request.json['cluster_name']
    data = get_dataset(cluster_name)
    return make_response(jsonify(data))



こうやって、Flaskを APIゲートウェイ的にどんどん作っていけます
ポイントは、Flaskからの返り値を json形式にしてやることで、javascriptで扱いやすくなります

return make_response(jsonify(data))


基本的には、追加していく API用のデコレータと関数は短めにして、共通関数を充実させていく感じですね
<app.py>

これで Elasticsearchにデータが入っている状態で、クラスタ名を入力し、表示ボタンを押してやれば、取得したデータが表示されます


React データ表示部分は

とりあえず表示していますが、React での Object 表示部分にはまだ触れていないので、また次回に