Reactサンプルアプリ開発 プラニングポーカー (5) 画面遷移

Poker サンプル開発

今回は、トップ画面からポーカーを行う「場」の画面への遷移を実装する。トップ画面は以下。

トップ画面

場名とニックネームを入力し「場を開く」をクリックすると、以下の画面に遷移するようにしたい。

場の画面

Flaskど素人なので、基本的なところから調べつつ実装。
まずトップ画面のフォームはTopPageコンポーネントに配置しているので、そこを修正。

export const TopPage: FunctionComponent = () => {
  return (
    <>
      <header className="header">
        <h1 className="title">Planning Poker</h1>
        <p className="description">
          チームメンバーでプラニング・ポーカーを行いましょう!<br />
            場名とニックネームを入力して開始します。
        </p>
      </header>
      <main>
        <form className="openForm" action="/table/open" method="POST">
          <input name="tablename" type="text" required placeholder="場名" />
          <input name="nickname" type="text" required placeholder="ニックネーム" />
          <input type="submit" value="場を開く" />
        </form>
      </main>
    </>
  )
}

action属性にパスを、method属性はPOSTを指定する。

Flaskのサーバーアプリケーション。

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

POSTのみを受けるようにするには、method=["POST"]を指定すればいいんだな(1行目)。リクエストパラメータはrequest.formから取得する(3-4行目)。UUIDをキーとし、場を開くURLへリダイレクトさせる(8行目)。

リダイレクトのリクエストは以下のメソッドが受け付ける。

@app.route("/table/<table_id>", methods=["GET"])
def table(table_id):
    table = tables[table_id]
    table_name = table["NAME"]
    player_name = table["PARENT"]
    html = render_template("table.html", table_name=table_name, player_name=player_name)
    return html

パス変数を<変数名>で記述することで(1行目)、メソッドの引数で受け取ることができる(2行目)。render_templateの第2引数以降にキー名=変数を列挙して渡すことで、テンプレート側で利用できるようになる(6行目)。

テンプレートHTMLファイル。

<body>
    <div id="app"></div>
    <script>
        var tableProps = {
            tableName: "{{ table_name }}",
            playerName: "{{ player_name }}",
        };
    </script>
    <script src="/js/table.bundle.js"></script>
</body>

アプリケーションから渡されたデータは{{ キー名 }}で参照し埋め込むことができる。ここではJavaScriptのオブジェクトのプロパティに値としてセットしている。
これらの値はReactコンポーネントに渡したいので、グローバル変数としてwindowに定義した。

さて、React側。トップレベルのコンポーネントは以下のようになった。

declare var tableProps: any;

ReactDOM.render(
  <React.StrictMode>
    <TablePage {...tableProps} />
  </React.StrictMode>,
  document.getElementById('app')
);

HTML側でグローバル変数定義したtablePropsの値をTablePageコンポーネントに渡したいので、スプレッド構文を用いてプロパティに展開して渡す(5行目)。
そのままだとTypeScriptのエラーとなってしまうので、declareをしている(1行目)。この辺はちゃんとわかってないのだが…

サーバーアプリからReactへのデータ受け渡しの王道実装がわからないので今後調べたいが、ひとまず画面遷移はできるようになった。

コメント

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