RailsとReactJSを用いてちょっとした掲示板を作ってみましょう vol.2

RailsとReactJSを用いてちょっとした掲示板を作ってみましょう vol.2

RailsとReactJSを用いてちょっとした掲示板を作ってみましょう vol.2

RailsとReactJSを用いてちょっとした掲示板を作ってみましょう vol.2 へのコメントはまだありません

はじめに

RailsとReactJSを用いてちょっとした掲示板を作ってみましょうというのが今回のコンセプト。
前回のVol.1は掲示板一覧を表示することだけで終わってしまいましたが、今回は本格的な
掲示板機能を実装してみます。多分長くなると思いますので、よろしくお付き合いください。

前回に引き続き、これから何回かにわたり連載する内容はGitHubの下記のURLで公開しています。
https://github.com/h-mito/rails_with_react

ステートの管理やら、イベントの引き渡し方がいまいちわからないという方は、
Railsとは関係ない ToDoListの記事 を参照してみてください。

完成イメージ

こんな感じのものができればいいなという理想型です。
rails-17

これをパーツ(ReactJSのクラス)に分解してみるとこんな感じになると思います。

rails-7

いざ開始

Reactコンポーネントファイルの作成

app/assets/javascripts/components/board_and_commen.js.jsx
ファイルを作成します。
rails g でやってもいいのですが、どうせ全部消しちゃうので手で作りましょう。

では、ファイルには以下のような感じで最上層部のクラスとなる
BoardAndCommentクラスを定義しましょう。

[bash]
class BoardAndComment extends React.Component{
constructor(props){
super(props);
}

render(){
return (

空っぽ。

);
}
}

[/bash]

Viewファイルの作成と、コントローラー・routes調整

app/views/boards/bandc.html.erb
にViewファイルを作ります。

中身は

[bash]
<%= react_component('BoardAndComment') %>

[/bash]

コントローラーにメソッドを追加します。
app/controllers/boards_controller.rb

[bash]

class BoardsController < ApplicationController def index @boards = Board.all end def bandc @boards = Board.all end end [/bash] routes.rbに1行ルートを追記します。 config/routes.rb [bash] get 'boards/bandc' [/bash]

動作確認

[bash]
$ rails s
[/bash]

ブラウザーで
http://localhost:3000/boards/bandc

こんな感じのものが表示されれば成功です。

rails-9

2階層目となる3つのクラスを定義して、トップレベル(1階層目)のrenderメソッドで
2階層目をレンダーする

ここでは2階層目となる3つのクラスを定義します。
3つのクラスは先ほどと同じように単純に固定文字を出力するだけです。

[bash]
class BoardAndComment extends React.Component{
constructor(props){
super(props);
}

render(){
return (


);
}
}

class BoardList2 extends React.Component{
constructor(props){
super(props);
}

render(){
return (

掲示板一覧を表示する場所です。

);
}

}

class CommentAdd extends React.Component{
constructor(props){
super(props);
}

render(){
return (

掲示板に投稿を追加する機能を表示する場所です。

);
}

}

class CommentList extends React.Component{
constructor(props){
super(props);
}

render(){
return (

掲示板内の投稿一覧を表示する場所です。

);
}

}

[/bash]

CSSの調整

app/assets/stylesheets/boards.scss
に以下を追記。

[bash]
div.left-side{
float: left;
width: 400px;
}

div.right-side{
float: left;
width: 600px;
}

[/bash]

動作確認

[bash]
$ rails s
[/bash]

ブラウザーで
http://localhost:3000/boards/bandc

こんな感じのものが表示されれば成功です。

rails-10

ステートで管理するものを考える

では掲示板に投稿する機能全体でステートとして管理しなきゃならないものは何でしょうか?
変化しそうなものに掲示板一覧・投稿文字を入力するエリアに入力された文字、投稿ユーザー、投稿一覧
の4つほどが考えられます。

今回の最終目標は選択した掲示板に投稿が追加できる というものなので、
掲示板一覧は 最初に読み込んだ値から不変ですので、ステートとして管理する必要はなし。
投稿文字に関しては、毎度毎度違う文字が入力されるので管理する必要あり。
投稿ユーザーは普通の掲示板であればログインした人のIDを用いるので、変化しませんが・・
ログイン処理を設けない、今回の掲示板では投稿の際にユーザーIDをSelectボックスで選択することにします。
つまり変化するので管理する必要ありです。
投稿対象の掲示板も変化するので管理する必要ありです。
投稿一覧も管理する必要があります。

ちょっと難しいかもですね。これ、慣れですので、だんだんわかってくると思います。
つまりこれだけの機能はあるけど、ReactJSで管理するステートは
投稿する文字 と 投稿するユーザー と投稿対象の掲示板 と投稿一覧の4つだけということになります。

で、どこで管理するかというとトップレベルのクラスであるBoardAndCommentクラスです。
board_title と board_descriptionについては、それほど重要なステートではないので、
今のところは無視しておいてください。

BoardAndCommentクラスにこのステート管理部分を追記してみましょう。

コンストラクター(constructor)で値を初期化して、投稿文字が変化した時にステートを
変化させるメソッド(handleCommentChange)を定義して、
レンダーメソッドで、CommentAddクラスをレンダーする際に
CommentAddクラス内で起こるイベントを自分のクラスで処理できるように記述を追加します。

投稿ユーザーが変化した時にステートを
変化させるメソッド(handleUserChange)を定義して、
レンダーメソッドで、CommentAddクラスをレンダーする際に
CommentAddクラス内で起こるイベントを自分のクラスで処理できるように記述を追加します。

残りの2つもおいおい説明します。

[bash]
class BoardAndComment extends React.Component{
constructor(props){
super(props);
this.state = {comment: ”, user_id: 1, board_id: -1, comments: [], board_title: ”, board_description: ”};
}

handleCommentChange(cm){
this.setState({comment: cm});
}

handleUserChange(id){
alert(id);
}

handleBoardSelect(id){
alert(id);
}

render(){
return (

this.handleBoardSelect(id)}
/>
this.handleUserChange(uid)}
onCommentChange={(cm) => this.handleCommentChange(cm)} />

);
}
}

[/bash]

掲示板一覧を実装する

これは前回やった内容とほぼ同じですので、ソースだけ提示して、
変化しているごく僅かな部分だけ説明します。

Viewの調整
[bash]
<%= react_component('BoardAndComment', {datas: @boards}) %>

[/bash]

まずはトップレベルのBoardAndCommentクラスの変化箇所。
renderメソッド内で BoardList2をレンダーしている部分で
datasアトリビュートに this.props.datas を渡しています。

[bash]
class BoardAndComment extends React.Component{
constructor(props){
super(props);
this.state = {comment: ”};
}

handleCommentChange(cm){
this.setState({comment: cm});
}

render(){
return (

this.handleCommentChange(cm)} />

);
}
}

[/bash]

次に2階層目のBoardList2クラス。renderメソッドで BoardList2クラスをレンダーする際に
BoardList2クラス内で起こるであろう掲示板選択のイベント(onBoardSelect)を自分の
クラスのメソッド内で処理させている。
もうひとつは、その処理も自分ではハンドリングしようがないので、もう1階層上のクラスに
任せている(handleBoardSelect)

[bash]
class BoardList2 extends React.Component{
constructor(props){
super(props);
}

handleBoardSelect(id){
this.props.onBoardSelect(id);
}

render(){
var lists = [];
var i;
for (i = 0; i < this.props.datas.length; i ++){ var data = this.props.datas[i]; lists.push( this.handleBoardSelect(id)}
/>);
}

return (

掲示板一覧を表示する場所です。
{lists}

);
}

}

[/bash]

最後に3階層目のクラスであるBoardLine2クラス。
行の右端に選択ボタンがあり、そのクリック処理を
onBoardSelectイベントとして1回層上のクラスに任せている。

[bash]
class BoardLine2 extends React.Component{
constructor(props){
super(props);
}

handleOnClick(){
this.props.onBoardSelect(this.props.data.id);
}

render(){
return (


);
}
}
[/bash]

最後の最後に見栄え調整のためのCSS
[bash]
div.blist2{
.board-title{
display: inline-block;
width: 320px;
}
}
[/bash]

動作確認

[bash]
$ rails s
[/bash]

ブラウザーで
http://localhost:3000/boards/bandc

こんな感じのものが表示されれば成功です

rails-11

イベントの上位階層への連携

BoardLine2クラスの「選択ボタン」のクリック処理は1つ上の階層までは伝えましたが、
1つ上の階層がBoardList2クラスなので、もう1階層上まで伝えてあげなきゃなりません。

で、どうするかというと、やり方はほぼ同じで
BoardList2クラスをレンダーする際にイベント処理(onBoardSelect)を定義してあげて、
トップレベルクラスのメソッドで処理できるようにします。

[bash]
class BoardAndComment extends React.Component{
constructor(props){
super(props);
this.state = {comment: ”, user_id: 1, board_id: -1, comments: [], board_title: ”, board_description: ”};
}

handleCommentChange(cm){
this.setState({comment: cm});
}

handleBoardSelect(id){
alert(id);
}

render(){
return (

this.handleBoardSelect(id)}
/>
this.handleCommentChange(cm)} />

);
}
}
[/bash]

動作確認

[bash]
$ rails s
[/bash]

ブラウザーで
http://localhost:3000/boards/bandc

一覧が表示されて、選択ボタンをクリックすると、こんな感じのものが表示されれば成功です
rails-12

投稿を追加する部分を実装する

画面左側の掲示板一覧を表示する部分はほぼ実装できたので、今度は投稿を追加する部分
つまり画面の右上の部分について説明していきます。

投稿する対象となる掲示板は画面左の一覧で「選択ボタン」をクリックしたものが対象になりますので、
右上の機能としては考える必要はありません。
右上の機能つまり CommentAddクラスの機能として必要なのは、
投稿の文字が変化したことをキャッチすること、投稿ユーザーが変化したことをキャッチすること。
投稿ボタンがクリックされたことをキャッチすること。
そしてそれらを上位クラスへ伝えてあげることです。

CommentAddクラス

では CommentAddクラスを実装していきましょう。

[bash]
class CommentAdd extends React.Component{
constructor(props){
super(props);
}

handleOnUserChange(e){
this.props.onUserChange(e.target.value);
}

handleOnCommentChange(e){
this.props.onCommentChange(e.target.value);
}

handleCommentAdd(){
this.props.onCommentAdd();
}

render(){
var users = [];
var i;
for (i = 0 ; i < this.props.users.length ; i++){ var user = this.props.users[i]; users.push();
}

return (

掲示板に投稿を追加する機能を表示する場所です。











日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)

Back to Top