Reactサンプルアプリ開発 プラニングポーカー (6) Ajaxでプレイヤーリストをフェッチ

Poker サンプル開発

トップページから場を開いたあとに表示されるプレイヤーはダミーデータを用いていたが、実際のデータを取得して表示するように修正したい。
トップページで以下のように入力すると

トップページ

遷移後のページで以下のように表示されるようにする。(親プレイヤーのみが表示される)

場のページ

まずはサーバー(Flask)側。
場を開いたタイミングで、プレイヤーの配列に親を入れてグローバル変数に保存しておく。

@app.route("/table/open", methods=["POST"])
def open():
    table_name = request.form["tablename"]
    parent_name = request.form["nickname"]
    table_id = str(uuid.uuid4())
    players = [parent_name]
    table = {
        "ID": table_id,
        "NAME": table_name,
        "PARENT": parent_name,
        "PLAYERS": players,
    }
    tables[table_id] = table
    return redirect(f"/table/{table_id}")

次に、プレイヤーリストを取得するためのエンドポイント。

@app.route("/table/<table_id>/players")
def players(table_id):
    table = tables[table_id]
    players = table["PLAYERS"]
    return jsonify({"players": players})

JSONでレスポンスを返すために、Flaskのjsonifyを利用した(5行目)。

次にクライアント側だが、Ajax処理にはaxiosを利用するため、まずはインストール。

$yarn add axios

インポート。

import axios from 'axios';

ReactのuseEffectもインポートを追加しておく。

import React, { FunctionComponent, useState, useEffect } from "react";

次に関数コンポーネント内にAjax処理を記述する。
プレイヤーリストの取得、表示はコンポーネントが最初に表示されたときに一度だけ行いたい。クラスコンポーネントならcomponentDidMount()だろうが、関数コンポーネントではライフサイクルメソッドは使えないので、どこに書くべきだろうか?
公式サイトに以下のような記述があった。

React のライフサイクルに馴染みがある場合は、useEffect フックを componentDidMount と componentDidUpdate と componentWillUnmount がまとまったものだと考えることができます。

というわけでuseEffectを使おう。

export const TablePage: FunctionComponent<TableProps> = (props) => {
  const [bidding, setBidding] = useState(true);
  const [players, setPlayers] = useState<PlayerProps[]>([]);

  useEffect(() => {
    axios.get(`/table/${props.tableId}/players`)
      .then((res) => {
        const players: PlayerProps[] =
          res.data.players.map((p: string) => {
            return {
              name: p,
              icon: 1,
              bid: "",
              open: false,
            }
          });
        console.log(`Got ${players.length} players by ajax call.`)
        setPlayers(players);
      }).catch((error) => {
        console.log("通信失敗")
        console.log(error.status);
      });
  }, []);

useEffectの第1引数のアロー関数内にaxiosを使ったAjax処理を記述した(5行目)。
子コンポーネント(Players)が要求するプロパティの型に変換(8-16行目)した後、useStateで作成したsetPlayers関数をコールしてステート変数をアップデートする(18行目)。

一度だけ処理を行うようにするため、useEffectの第2引数には空の配列を渡している(23行目)。これを入れないと、コンポーネントのレンダリングが走る度にAjax処理が呼び出されてしまう。

第2引数の配列の意味合いはまったくわかっていないので、ちゃんとドキュメントを読んで理解しなければ。

コメント

タイトルとURLをコピーしました