Node.js
PostgreSQL
react.js
superagent

今からはじめるReact.js〜サーバーとの通信〜

More than 1 year has passed since last update.

前回→今からはじめるReact.js〜仮想環境を作成する〜


React.jsからサーバー通信


SuperAgant

React.jsでAjax通信する場合、jQueryを利用するか、その他の手段を使うか検討すると思いますが、Ajax通信するためだけにjQueryを使うのは無駄が多いので、SuperAgantを利用することにします。

SuperAgantの使い方については、

http://qiita.com/hashrock/items/3113690bb3de5bba639b

の解説がわかりやすかったです。

インストールは次の通りです。

$ npm install superagent --save


テーブルを作成する

今回、ユーザーを登録できるのと、ユーザーリストを表示できるように実装します。

サーバー通信の実装を行う前に、ユーザーテーブルを作成します。

カラムはnameとmailだけの単純なものです。


pgAdminのインストール

自端末側でデータベースを見ながら作業したいので、ツールをインストールします。

pgAdminを使用することとします。

Mac->http://www.pgadmin.org/download/macosx.php

Win->http://www.pgadmin.org/download/windows.php

から圧縮ファイルをダウンロードしてインストールします。

インストールしたら、起動してサーバーの追加を行います。

スクリーンショット 2015-10-16 16.35.52.png

パスワードはpostgreSQLをインストールした際にpostgresユーザーに付与したパスワードのことです。

OKをクリックしたらサーバーが追加されます。

(Saving passwordsの画面が出たらOKをクリック)

スクリーンショット 2015-10-16 16.38.49.png


usersテーブルを作成

postgresデータベースのpublicスキーマにusersテーブルを作成します。

「テーブル」ディレクトリを右クリックして、「新しいテーブル」をクリックします。

スクリーンショット 2015-10-16 16.40.46.png

テーブル定義は以下の通りです。

スクリーンショット 2015-10-16 16.42.07.png

「列」をクリックして、カラムの追加を行います。

スクリーンショット 2015-10-16 16.43.37.png

追加ボタンをクリックします。

プライマリーキーとなるidを追加します。データ型はserialとしておきます。

スクリーンショット 2015-10-16 16.45.30.png

nameとmailについても以下のように追加します。

name

スクリーンショット 2015-10-16 16.47.17.png

mail

スクリーンショット 2015-10-16 16.48.19.png

こんな感じになります。

スクリーンショット 2015-10-16 16.48.51.png

最後に、プライマリーキーを指定します。

「制約」で追加ボタンをクリックします。

スクリーンショット 2015-10-16 16.49.43.png

プロパティは、以下のようにします。

スクリーンショット 2015-10-16 16.50.59.png

列でidを指定して追加ボタンをクリックします。

スクリーンショット 2015-10-16 16.52.15.png

OKボタンをクリックすると、以下のように表示されるはずです。

スクリーンショット 2015-10-16 16.53.05.png

OKをクリックして設定を確定します。

下記のようにテーブルが作成されているはずです。

スクリーンショット 2015-10-16 16.55.08.png


React.jsの実装

テーブルが作成できたら、ソースを書きましょう。body.jsxを編集します。

UserBoxコンポーネントの中にAjaxの処理を追記します。

今回実装したい処理としては、

・画面表示時にusersテーブルからデータを取得してリストに表示する

・追加ボタンをクリックした際にusersテーブルに入力データを追加してリストを最新データで再表示する

になります。

画面が表示された際になんらかのイベントを行いたい場合はcomponentDidMountメソッドを記述します。

更新するイベントは既存のhandleAddUserを編集するだけでいけそうですね。


body.jsx

//フォームとリストを一つにしたもの

var UserBox = React.createClass({
getInitialState:function(){
return {userData:[]};
},
handleAddUser:function(name, mail){
//ユーザーをDBに登録する
//ユーザー一覧を取得する(結果をthis.state.userDataにセット)

//var data = this.state.userData;
//data.push({name: name, mail: mail});
//this.setState({userData: data});
},
componentDidMount:function(){
//ユーザー一覧を取得する(結果をthis.state.userDataにセット)
},
render:function(){
return(
<div style={{width:"300px"}}>
<UserForm addUser={this.handleAddUser}/>
<hr/>
<UserList userData={this.state.userData}/>
</div>
);
}
});


やることが決まったらプログラムを書きます。


ユーザーをDBに登録するイベントの作成

postメソッドを実行するように書きます。


body.jsx

var React = require('react');

var ReactDOM = require('react-dom');
var request = require('superagent');
:
:
:
handleAddUser:function(name, mail) {
var url = "/post_user";
//ajax通信する
request
.post(url)
.send({name: name, mail: mail})
.end(function(err, res){
if (err) {
alert(res.text);
}
var map = JSON.parse(res.text);
//表示されている値を更新
this.setState({userData: map});
}.bind(this));
}

まずはsuperagentをインポートします。

次に、

postメソッドを使ってサーバー通信します。

urlは http://192.168.33.10:5000/post_user

postしたいデータをsendで設定。

postの結果はendで処理します。

通信が成功した場合、サーバー側からはユーザー一覧を返してもらいます。

返されるデータはテキストで返されますので、処理しやすいようにJSONオブジェクトに変換します。

最後にsetStateします。これでリストの表示が更新されます。


ユーザー一覧を取得するイベントの作成

getメソッドを定義します。


body.jsx

  getUsers:function(name, mail) {

var url = "/get_users";
//ajax通信する
request
.get(url)
.query({})
.end(function(err, res){
if (err) {
alert(res.text);
}
var map = JSON.parse(res.text);
//表示されている値を更新
this.setState({userData: map});
}.bind(this));
}

urlは http://192.168.33.10:5000/get_user

getする際の条件があればqueryで設定(今回は無し)。queryは省略しても実行できます。

以上をまとめると、以下のようになります。

//フォームとリストを一つにしたもの

var UserBox = React.createClass({
getInitialState:function(){
return {userData:[]};
},
getUsers:function(name, mail) {
var url = "/get_users";
//ajax通信する
request
.get(url)
.query({})
.end(function(err, res){
if (err) {
alert(res.text);
}
var map = JSON.parse(res.text);
//表示されている値を更新
this.setState({userData: map});
}.bind(this));
},
handleAddUser:function(name, mail){
var url = "/post_user";
//ajax通信する
request
.post(url)
.send({name: name, mail: mail})
.end(function(err, res){
if (err) {
alert(res.text);
}
var map = JSON.parse(res.text);
//表示されている値を更新
this.setState({userData: map});
}.bind(this));
},
componentDidMount:function(){
this.getUsers();
},
render:function(){
return(
<div style={{width:"300px"}}>
<UserForm addUser={this.handleAddUser}/>
<hr/>
<UserList userData={this.state.userData}/>
</div>
);
}
});


Node.jsの実装

サーバーサイドも実装しましょう。


ライブラリをインストール

まず手始めに、各種必要なライブラリをインストールします。

1.postされたデータを扱うために、body-parserというライブラリをインストールします。

2.postgreSQLと通信するためにpgというライブラリをインストールします。

$ npm install body-parser pg --save


pgのヘルパーjs作成

postgreSQLに接続してSQLを実行するまでの手続きは定型の処理のため、ヘルパー用のjsファイルを作ってしまいましょう。


pghelper.js

var pg = require('pg'),

databaseURL = 'postgres://postgres:{パスワード}@127.0.0.1:5432/postgres';

/**
* poatgreSQLに接続してSQLを実行する
* @param sql 実行したいSQL
* @param values SQLに指定するパラメータ
* @param callback SQL実行後、処理するイベント
*/

exports.query = function(sql, values, callback) {
console.log(sql, values);

pg.connect(databaseURL, function(err, conn, done) {
if (err) {
return callback(err);
}
try {
conn.query(sql, values, function(err, res) {
done();
if (err) {
callback(err);
} else {
callback(null, res.rows);
}
});
} catch(e) {
done();
callback(e);
}
});
};


終わったら、usersの入出力を実装するためのjsファイルを作成します。

serverフォルダに、users.jsを作成します。


users.js

var db = require('./pghelper');

/**
* ユーザー一覧を取得します
* @param req
* @param res
* @param next
* @returns {*|ServerResponse}
*/

function getUsers(req, res, next) {
db.query(
'SELECT * FROM users',
[],
function(err, datas){
if (err){
console.log(err);
return res.status(400).send('エラーが発生しました');
}
return res.send(JSON.stringify(datas));
}
);
}


エラーが発生した場合、クライアント側にステータス400を返すとともに、「エラーが発生しました」というメッセージを返すようにします。

正常にデータが取得できた場合は、JSON形式で返されたデータをテキスト形式にして返します。


users.js

/**

* ユーザーを登録します
* @param req
* @param res
* @param next
* @returns {*|ServerResponse}
*/

function postUser(req, res, next) {
var user = req.body;
db.query(
'INSERT INTO users (name, mail) VALUES ($1, $2) ',
[user.name, user.mail],
function(err, datas){
if (err){
console.log(err);
return res.status(400).send('エラーが発生しました');
}
return next();
}
);
}

exports.getUsers = getUsers;
exports.postUser = postUser;


ユーザー登録の場合、更新が成功したら、nextを実行します。nextにはgetUsersがserver.jsから指定される想定です。

次に、

server.jsを編集します。


server.js

var express = require('express'),

bodyParser = require('body-parser'),
users = require('./users');
var app = express();

body-parserおよび、作成したusers.jsをインポートします。


server.js

//ポートの指定

app.set('port', process.env.PORT || 5000);

//ルートパスの指定
var clientPath = __dirname.replace("/server", "/client");
app.use('/', express.static(clientPath));

//bodyParserの設定
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));

//urlと呼びたいメソッドの紐付け
app.post('/post_user', users.postUser, users.getUsers);
app.get('/get_users', users.getUsers);


bodyParserの設定を行い、postで送られてきたデータを受け付けられるようにします。

また、クライアント側から指定したurlに応じたメソッドを実行できるように紐付けを行います。実行したいメソッドは複数指定できます。

上記では、postUserが終わったらgetUsersが呼ばれるようにしています。

ここまで実装したら、

jsxをコンパイル(gulp browserify)して、

サーバー起動(node server/server.js)し、

ブラウザで確認してみましょう。

ユーザーが登録できて、リストも再表示されればOKです。


捕捉

古いnodeのバージョンを使用している場合、インストールしたpgのバージョンとの対応関係により、接続エラーが発生する場合があります。

その場合は、pgのバージョンを固定してinstallしなおしてみてください。

//バージョンを固定してインストール

$ npm install pg@4.4.3 --save


サンプルソース

https://github.com/kunitak/react-tutorial/tree/day7

次回→今からはじめるReact.js〜画面遷移〜