Reactチュートリアル入門: Pythonサーバーサイド連携編
チュートリアル | React
がなくなったようで。。良いチュートリアルだったのに。。
まあとりあえず、前回は
クライアントサイドのみでWebサイトを表示したので、
今回はサーバーサイドで取得したデータをクライアントサイドに渡して表示させる。
とは言っても、JSONファイルを表示するだけなので、非常に簡単。
ただし、サーバーサイドはNode.jsではなく、Pythonを使う。
その前にまず、前回のReactコードを少しカスタマイズする。
クライアントサイドのカスタマイズ
CommentBox
前回、シンプルだったCommentBoxに色々追記する。
loadCommentsFromServer: function() { $.ajax({ url: this.props.url, dataType: 'json', cache: false, success: function(data) { this.setState({data: data}); }.bind(this), error: function(xhr, status, err) { console.error(this.props.url, status, err.toString()); }.bind(this) }); },
Ajax通信を行う。urlは、後ほどReactDOM.renderでCommentBoxに渡される。 これがサーバーサイドへのパスになる。dataはサーバーサイドから返ってきたデータ。
getInitialState: function() { return {data: []}; },
クライアントサイドのdataの初期化。dataはObjectのArrayなので[]となる。
componentDidMount: function() { this.loadCommentsFromServer(); setInterval(this.loadCommentsFromServer, this.props.pollInterval); },
DOMに関わる初期化。 loadCommentsFromServerで設定したAjaxリクエストや、リフレッシュ頻度を指定するsetIntervalの登録など、 server-side rendering時には必要ない初期化処理についてはこの中で行う。
以上より、今回のCommentBoxは次のようになる。
var CommentBox = React.createClass({ loadCommentsFromServer: function() { $.ajax({ url: this.props.url, dataType: 'json', cache: false, success: function(data) { this.setState({data: data}); }.bind(this), error: function(xhr, status, err) { console.error(this.props.url, status, err.toString()); }.bind(this) }); }, getInitialState: function() { return {data: []}; }, componentDidMount: function() { this.loadCommentsFromServer(); setInterval(this.loadCommentsFromServer, this.props.pollInterval); }, render: function() { return ( <div className="commentBox"> <h1>Comments</h1> <CommentList comments={this.state.data} /> </div> ); } });
ReactDOM.render
設定したCommentBoxに、ReactDOM.renderでパラメーターを渡す。 サーバーサイドのパスとなるurlと、リフレッシュ頻度となるpollIntervalを指定する。 前回はurlキーではなく、dataキーにクライアントサイドで定義したdataを渡していた。 pollIntervalは公式では2000(2秒)だが、短すぎるので2000秒としておく。
ReactDOM.render( <CommentBox url="/api/comments" pollInterval={2000000} />, document.getElementById('content') );
Pythonサーバーサイド
Pythonのサーバーサイドは、Flaskを使っている。 Flaskは僕も知らないので、ググって下さい。 でもFlaskはまったく悩むことなく簡単に使えるようで、 クライアントサイドで指定したurl='/api/comments' [check1!] のすぐ下のcomments_handler() の中でデータを取得して返している。 今回はGETのみなので、単純にserver.pyと同じディレクトリーに置かれたcommnet.jsonを読み込んで [check2!] 、 json形式にPythonで適切に変形して、クライアントサイドに返している [check3!] ことが分かる。
import json import os import time from flask import Flask, Response, request app = Flask(__name__, static_url_path='', static_folder='public') app.add_url_rule('/', 'root', lambda: app.send_static_file('index.html')) # client and server side with json file @app.route('/api/comments', methods=['GET', 'POST']) # Check1! def comments_handler(): with open('comments.json', 'r') as f: comments = json.loads(f.read()) # Check2! if request.method == 'POST': new_comment = request.form.to_dict() new_comment['id'] = int(time.time() * 1000) comments.append(new_comment) with open('comments.json', 'w') as f: f.write(json.dumps(comments, indent=4, separators=(',', ': '))) return Response( json.dumps(comments), # Check3! mimetype='application/json', headers={ 'Cache-Control': 'no-cache', 'Access-Control-Allow-Origin': '*' } ) if __name__ == '__main__': app.run(port=int(os.environ.get("PORT", 3000)), debug=True)
実行
$ python server.py
上記のコマンドを実行すると、以下のように表示されるはず。