###前提・実現したいこと
RailsアプリケーションにReactを導入し、その中でAjaxを利用して投稿をPOSTする機能を作成しています。
POSTする部分までは作成できたのですが、さらに、POST後にPOSTした内容を表示する機能を作成したいと思っています。
Rails 4.2.2
Ruby 2.0.0
React
Ajax
で開発をしています。
###実装がうまくいかない箇所
このスクリーンショット内の、テキストフォームの「POST」というテキストを
POSTボタンがクリックされた後にテキストフォームの上あたりに表示したいのですが
POST成功後、表示する部分を実装できずにいます。
現状では、POSTボタンタップ後、下記のようなサーバーログが表示され
POST自体は成功しています。
POST時のサーバーログ
1Started POST "/microposts" for ::1 at 2017-01-15 17:20:21 +0900 2Processing by MicropostsController#create as */* 3 Parameters: {"micropost"=>{"content"=>"POST"}} 4 User Load (0.2ms) SELECT "users".* FROM "users" WHERE 5 6中略 7 8Completed 302 Found in 16ms (ActiveRecord: 9.5ms)
ただ、上記のように投稿後に表示する部分がうまくいかず、下記のスクリーンショットのような表示となってしまいます。
本当は、ここでテキストフォームと「MessageBox」というテキストの間に投稿した内容を表示したいです!!
###該当のソースコード
reactで投稿する実装は、下記のサイトを参考にしています
http://ruby-rails.hatenadiary.com/entry/20151122/1448118932
まず、テキストフォームを生成して、POSTする内容を受け取るコードは次のようになっています。
javascript
1var MessageForm = React.createClass({ 2 handleSubmit: function(event) { 3 event.preventDefault(); 4 var user = this.refs.user.value.trim(); 5 // 親コンポーネントのMessageBocのイベントを呼び出す 6 this.props.onMessageSubmit( user ); 7 // フォームの内容を削除 8 this.refs.user.value = ''; 9 }, 10 11 // 投稿用のフォームを作成して、'user'として内容を受け取る 12 render: function() { 13 return ( 14 <form className="commentForm" onSubmit={this.handleSubmit}> 15 <input type="text" placeholder="Title" ref='user'/> 16 <input type="submit" value="Post" /> 17 </form> 18 ); 19 } 20}); 21
次に、上記のコードから投稿する内容を受取、AjaxでPOSTするコードが以下のようになっています。
javascript
1var MessageBox = React.createClass({ 2 getInitialState: function() { 3 // isLoading = true : ロード中を表示 4 return { messages: [], isLoading: true }; 5 }, 6 7...中略 8 9 // 投稿の内容をAjaxでPOST 10 handleMessageSubmit: function(message) { 11 $.ajax({ 12 url: 'microposts', 13 datatype: 'json', 14 type: 'POST', 15 beforeSend: function(xhr) {xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'))}, 16 data: { 17 micropost: { content: message } 18 }, 19 success: function(message) { 20 var newMessages = this.state.messages.concat(message); 21 this.setState({ messages: newMessages }); 22 }.bind(this), 23 error: function(_xhr, status, err) { 24 console.error(this.props.url, status, err.toString()); 25 }.bind(this) 26 }); 27 }, 28 29 render: function() { 30 var messageItems = this.state.messages.map(function(message) { 31 return ( 32 <MessageItem key={message.id} message={message}/> 33 ); 34 }); 35 36 // ボタンがクリックされた時に、投稿する内容を受け取ってhandleMessageSubmitに渡す 37 return ( 38 <div> 39 <h1>Message Box</h1> 40 <div className="messageBox"> 41 {messageItems} 42 <MessageForm onMessageSubmit={this.handleMessageSubmit}/> 43 </div> 44 </div> 45 ); 46 } 47}); 48
最後に、投稿した内容を表示するためのコードが下記のようになっています。
javascript
1var MessageItem = React.createClass ({ 2 render: function() { 3 return ( 4 <div className="message"> 5 <h2 className="messageUser">{this.props.message.user}</h2> 6 </div> 7 ); 8 } 9});
必要な情報などあれば、いっていただけると助かります。
###追記
編集依頼にいただいた内容ですが、handleMessageSubmitが実行された際には、下記のサーバーログが残っていました。
Started POST "/microposts" for ::1 at 2017-01-16 19:48:46 +0900 Processing by MicropostsController#create as */* Parameters: {"micropost"=>{"content"=>"サンプル"}} User Load (1.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 103]] (0.5ms) begin transaction SQL (3.0ms) INSERT INTO "microposts" ("content", "user_id", "created_at", "updated_at") VALUES (?, ?, ?, ?) [["content", "サンプル"], ["user_id", 103], ["created_at", "2017-01-16 10:48:46.294594"], ["updated_at", "2017-01-16 10:48:46.294594"]] (0.9ms) commit transaction Redirected to http://localhost:3000/home Completed 302 Found in 59ms (ActiveRecord: 5.5ms)
302が返ってきているようなのですが、これが問題なのでしょうか、、
もう1点、MessageItemの動きを調べている時に気づいた点があったので記載します。
まず、MessageItemが呼び出されていないかも、と思ったので、MessageItemメソッドの中身を
var MessageItem = React.createClass ({ render: function() { return ( <div className="message"> <h2 className="messageUser">{this.props.message.user}</h2> </div> ); } });
上記から下記に書き換えてみました。
「サンプル」というテキストを追加しています。
var MessageItem = React.createClass ({ render: function() { return ( <div className="message"> <h2 className="messageUser">サンプル{this.props.message.user}</h2> </div> ); } });
その後、実際に動かしてみると、Postボタンをタップする前には
上記のスクショのようになっているところ、
Postボタンタップ後に下記のスクショのように
「サンプル」というテキストが表示されました。
これでMessageItemが呼び出されていることは分かったのですが、
投稿した内容が表示されないというのは
MessageItem内の{this.props.message.user}の部分に
データがうまく渡っていないのでしょうか。。。
とりとめのない追記で申し訳ありませんが、見ていただけると大変助かります。
###さらに追記 01/17
コメントにいただいたように、success:の中でconsole.log(message)を記載してchromeで確認をしました。
htmlが吐き出されているようで、かなり長いログになっていました。。
※あまりに長いので、一部省略しています。
<!DOCTYPE html> <html> <head> <title>Ruby on Rails Tutorial Sample App</title> <link rel="stylesheet" media="all" href="/assets/account_activations.self-e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855.css?body=1" data-turbolinks-track="true" /> 中略 <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/r29/html5.min.js"> </script> <![endif]--> </head> <body style="color: rgb(27, 29, 34)"> <header class="navbar navbar-inverse"> <div class="container" style="margin-top: 100px;"> <a id="logo" href="/home">sample app</a> <nav> <ul class="nav navbar-nav navbar-right"> <li><a href="/home">Home</a></li> <li><a href="/help">Help</a></li> <li><a href="/users">Users</a></li> <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown"> Account <b class="caret"></b> </a> <ul class="dropdown-menu"> <li><a href="/users/103">Profile</a></li> <li><a href="#">Settings</a></li> <li class="divider"></li> <li> <a rel="nofollow" data-method="delete" href="/logout">Log out</a> </li> </ul> </li> </ul> </nav> </div> </header> <div class="landing"> <div class="alert alert-success">Micropost created!</div> <div class="container"> <div class="row col-md-12"> <h1> <section class="user_info"> <a href="/users/103"><img alt="example_sample@example.com" class="gravatar" src="https://secure.gravatar.com/avatar/1a51ab8ceafa101e9b36619b6c9b277d?s=80" /></a> <h1>example_sample@example.com</h1> <span><a href="/users/103">view my profile</a></span> <span>84 microposts</span> <div class="stats"> <a href="/users/103/following"> <a id="following" class="stat"> 1 following </a> </a> <a href="/users/103/followers"> <a id="followers" class="stat"> 0 followers </a> </a> 中略 </section> <div data-react-class="MessageBox" data-react-props="{}"></div> </div> </div> </div> <footer class="footer"> <small> The <a href="http://www.railstutorial.org/">Ruby on Rails Tutorial</a> by <a href="http://www.michaelhartl.com/">Michael Hartl</a> </small> <nav> <ul> <li><a href="/about">About</a></li> <li><a href="/contact">Contact</a></li> <li><a href="http://news.railstutorial.org/">News</a></li> </ul> </nav> </footer> <pre class="debug_dump">--- !ruby/hash:ActionController::Parameters controller: static_pages action: home </pre> </div> </body> </html>
また、chromeのconsoleをみると、もう一つエラーが表示されていました。
micropost.self-560a548….js?body=1:19 undefined "parsererror" "SyntaxError: Unexpected token < in JSON at position 0"
コードの該当部分は、POSTのajax内のerror:、下記の部分のようです。
console.error(this.props.url, status, err.toString());
よろしくお願いします。
###さらにさらに追記 1/17(2)
micropostsのcontrollerは下記のようになっています。
class MicropostsController < ApplicationController before_action :logged_in_user, only: [:create, :destroy, :show] before_action :set_micropost, only: [:destroy, :show] def create @micropost = current_user.microposts.build(micropost_params) if @micropost.save flash[:success] = "Micropost created!" redirect_to home_path else @feed_items = [] render 'static_pages/home' end end def destroy @micropost.destroy flash[:success] = "Micropost deleted" redirect_to request.referrer || home_path end def show messages = Micropost.find(params[:id]) render json: messages end private def micropost_params params.require(:micropost).permit(:content, :picture) end def set_micropost @micropost = current_user.microposts.find_by(id: params[:id]) redirect_to home_path if @micropost.nil? end end
回答1件
あなたの回答
tips
プレビュー