React + WP REST APIでコメント欄を作る(チュートリアル編)

「WP REST API触るならReactでやろうよ」という声が聞こえてきたとか聞こえてこなかったとかで、冬休みの自由研究的に触ってみました。

動作サンプルはありませんが、WordPressテーマに組み込んでしまっていて切り出すのがめんどくさいからですすみません。

Step0:gulpで環境構築したい方への参考記事

JavaScript – React.js + Babel + Browserify + gulp の環境を作ってみた – Qiita

この記事のgulpfile.jsなどを参考にすると割とすんなりいきました。

React実際に触る部分は今回は見なくても大丈夫です。

Step1:Reactのチュートリアルをやる

何はともあれまずはReactチュートリアルをやりましょう。

日本語ですし、コードも載ってるので何も考えずにひたすらコードを書いて動かしていきます。

CheckPoint:ページの一番下までやりきりましたか?

やってない方は横着せずにちゃんとやりましょう。

Step2:WP REST APIを組み込む

チュートリアルを最後までされた方は早速WP REST APIを組み込んでいきましょう。

書き換える箇所が複数箇所ありますので、デバッグしながらやるといいと思います。

1:WP REST APIを呼び出す

何はともあれAPIをよばないことには始まりません。
[html]
ReactDOM.render(
<CommentBox url="comments.json" pollInterval={2000} />,
document.getElementById(‘content’)
);
[/html]
の「url」をWP REST APIのコメントAPIに書き換えます。
[html]
ReactDOM.render(
<CommentBox url="https://example.com/wp-json/wp/v2/comments" pollInterval={2000} />,
document.getElementById(‘content’)
);
[/html]
これでWP REST APIにGET/POSTできるようになりました。

ただしJSONの中身がチュートリアルと異なりますのでこのままでは意図した表示になりません。

2:CommentListの値を修正する

まずはコメント一覧をちゃんと表示するようにしていきましょう。
[html]
var CommentList = React.createClass({
render: function() {
var commentNodes = this.props.data.map(function (comment) {
return (
<Comment author={comment.author}>
{comment.text}
</Comment>
);
});
return (
<div className="commentList">
{commentNodes}
</div>
);
}
});
[/html]
上記のコードを以下のように書き換えます。
[html]
var CommentList = React.createClass({
render: function() {
var commentNodes = this.props.data.map(function (comment) {
return (
<Comment author={comment.author_name} key={comment.id}>
<div dangerouslySetInnerHTML={{__html: comment.content.rendered}} />
</Comment>
);
});
return (
<div className="commentList">
{commentNodes}
</div>
);
}
});
[/html]
authorの値をauthor_nameから取得するように、
コメント本文をcontent.renderedから取得し、HTMLタグを出力するようにしています。

3:コメントを投稿するようにする

これでコメント一覧のGETはできるようになりましたので、次はコメント投稿(POST)できるようにします。
まずはフォームの値を調整します。

CommentForm書き換え前

[html]
var CommentForm = React.createClass({
render: function() {
return (
<form className="commentForm" onSubmit={this.handleSubmit}>
<input type="text" placeholder="Your name" ref="author" />
<input type="text" placeholder="Say something…" ref="text" />
<input type="submit" value="Post" />
</form>
);
}
});
[/html]

CommentForm書き換え後

先ほどのコードをこのように変更します。
[html]
var CommentForm = React.createClass({
render: function() {
return (
<form className="commentForm" onSubmit={this.handleSubmit}>
<input type="text" placeholder="Your name" ref="author_name" />
<input type="text" placeholder="Say something…" ref="content" />
<input type="text" placeholder="Post ID" ref="post" />
<input type="submit" value="Post" />
</form>
);
}
});
[/html]
ここではWP REST APIでPOSTできる値への書き換えと、投稿IDを指定できるようにフォーム項目を追加しています。
*余裕のある方はここの投稿IDもselectなどで表示できるようにしてみるといいかなと思います。

続いてフォームの値を受け取る部分を書き換えていきます。

handleSubmit書き換え前

[js]
handleSubmit: function(e) {
e.preventDefault();
var author = ReactDOM.findDOMNode(this.refs.author).value.trim();
var text = ReactDOM.findDOMNode(this.refs.text).value.trim();
if (!text || !author) {
return;
}
// TODO: サーバにリクエストを送信
ReactDOM.findDOMNode(this.refs.author).value = ”;
ReactDOM.findDOMNode(this.refs.text).value = ”;
return;
},
[/js]

ここは値の書き換えとコピペで項目追加だけで済ませています。

handleSubmit書き換え後

[js]
handleSubmit: function(e) {
e.preventDefault();
var author = ReactDOM.findDOMNode(this.refs.author_name).value.trim();
var text = ReactDOM.findDOMNode(this.refs.content).value.trim();
var id = ReactDOM.findDOMNode(this.refs.id).value.trim();
if (!text || !author || !id) {
return;
}
this.props.onCommentSubmit({author_name: author, content: text,post: id});
ReactDOM.findDOMNode(this.refs.author_name).value = ”;
ReactDOM.findDOMNode(this.refs.content).value = ”;
ReactDOM.findDOMNode(this.refs.id).value = ”;
return;
},
[/js]

最後にWP REST APIで処理する場合には不要なsetState処理を削除します。

handleCommentSubmit書き換え前

[js]
handleCommentSubmit: function(comment) {
var comments = this.state.data;
var newComments = comments.concat([comment]);
this.setState({data: newComments});
$.ajax({
url: this.props.url,
dataType: ‘json’,
type: ‘POST’,
data: comment,
success: function(data) {
this.setState({data: data});
}.bind(this),
error: function(xhr, status, err) {
this.setState({data: comments});
console.error(this.props.url, status, err.toString());
}.bind(this)
});
},
[/js]
この中に3つあるsetStateを残しておくと、「WP REST APIに投稿するコメントの値」と「WP REST APIにコメント投稿した結果」が「コメント一覧」と混ざってしまいます。
なので以下のように消しておきましょう。

handleCommentSubmit書き換え後

[js]
handleCommentSubmit: function(comment) {
var comments = this.state.data;
var newComments = comments.concat([comment]);
$.ajax({
url: this.props.url,
dataType: ‘json’,
type: ‘POST’,
data: comment,
success: function(data) {
this.loadCommentsFromServer();
}.bind(this),
error: function(xhr, status, err) {
console.error(this.props.url, status, err.toString());
}.bind(this)
});
},
[/js]
successの時に「this.loadCommentsFromServer();」でAPIをもう一度コールさせることで、新しいコメント一覧を取得するようにさせています。

エラー時の処理はあった方がいいとは思いますが、今回は力尽きたので省略しています。

おわりに

React + WP REST APIのちょうどいい練習台ないかなといろいろ探していたのですが、GETもPOSTも両方簡単に試せるReactチュートリアルが一番お手軽かなと思います。

チュートリアルらしくいろいろ抜けているところがあるので、各々でいろいろカスタマイズされていくと勉強にもなって面白いかもしれません。

Comment