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

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

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へのデータ受け渡しの王道実装がわからないので今後調べたいが、ひとまず画面遷移はできるようになった。
コメント