Flask と React でWebアプリを設計する練習として、フォームからPOSTでデータを送信/受信する簡単なWebアプリを作成してみました。
フォルダ/ディレクトリ構成
(アプリ用フォルダ) ├─ static │ └─ main.jsx ├─ templates │ └─ index.html └─ app.py
実行方法(ローカル)
まず、アプリ用フォルダをカレントディレクトリとして、PythonのFlaskローカルサーバを動かします。
>python app.py
その後、適当なブラウザで http://localhost/ にアクセスしてください。
実行例
まず、アプリを実行すると↓のような画面になります。
+,-ボタンを押すと、中央の数字がそれぞれ -1, +1 されます。
その後 Submit を押すとその数値がFlaskサーバにPOSTされます。
今回はテストなので、Flaskサーバの応答として送信したデータをそのまま返して alert
で表示しています。
プログラム
Python Flask (app.py)
今回は簡単な例として、POSTで送られてきた数値をそのまま返すような応答としています。
# -*- coding: utf-8 -*- from flask import Flask from flask import render_template, request, jsonify from pprint import pprint app = Flask(__name__) @app.route('/', methods = ['POST', 'GET']) def index(): if request.method == 'POST': result = request.get_json() pprint(result) return jsonify({"test_post": f"OK: {result}"}) return render_template('index.html') if __name__ == "__main__": app.run("0.0.0.0", 80, debug=True)
JavaScript (main.jsx)
fetch
を使ってPOSTし、正常な応答であれば中身をalert
で表示します。
class ReactPostExample extends React.Component { state = { value: 0, } constructor() { super(); this.increment = this.increment.bind(this); this.decrement = this.decrement.bind(this); this.handleSubmit = this.handleSubmit.bind(this); } get value() { return this.state.value; } increment() { const { max } = this.props; if (typeof max === 'number' && this.value >= max) return; this.setState({ value: this.value + 1 }); } decrement() { const { min } = this.props; if (typeof min === 'number' && this.value <= min) return; this.setState({ value: this.value - 1 }); } handleSubmit = async () => { const response = await fetch("/", { method: "POST", headers: {'Content-Type' : 'application/json'}, body: JSON.stringify(this.value) }) if (response.ok) { let json = await response.json(); alert(json["test_post"]) } else { alert("HTTP-Error: " + response.status); } } render = () => { return ( <div className="input-bpm" style={this.props.style}> <button type="button" onClick={this.decrement}>−</button> <span> {this.value} </span> <button type="button" onClick={this.increment}>+</button> <p><button type="button" onClick={this.handleSubmit}>Submit</button></p> </div> ) } } ReactDOM.render( <div> <ReactPostExample min={-10} max={10} /> </div>, document.getElementById('root') )
HTML (index.html)
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <meta http-equiv="Cache-Control" content="no-cache"> <title>ReactPostExample</title> <script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script> <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script> <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script> </head> <body> <div id="root"></div> <script type="text/babel" src="static/main.jsx" defer></script> </body> </html>