🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

Q&A

解決済

2回答

2344閲覧

[React.js]stateが正常にsetされない。

wisheebell

総合スコア7

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

0グッド

1クリップ

投稿2019/09/09 00:52

前提・実現したいこと

現在React.jsでテキストのCRUDを実装しています。
投稿したデータはaxiosを使ってrailsサーバーのデータベースに保存されます。

投稿されたテキストを後から編集する機能を実装する際に、stateがうまく反映されず困っています。。。
handleSubmit内でsetStateをしているのですが、stateの内容が変更されていません。

該当のソースコード

Javascipt

1import React, { Component } from 'react'; 2import update from 'react-addons-update'; 3import axios from 'axios'; 4import TextField from '@material-ui/core/TextField'; 5import Button from '@material-ui/core/Button'; 6 7class Form extends Component { 8 constructor(props) { 9 super(props); 10 this.state = { 11 post: {}, 12 title: '', 13 content: '' 14 }; 15 this.handleChange = this.handleChange.bind(this); 16 this.handleContentChange = this.handleContentChange.bind(this); 17 this.handleSubmit = this.handleSubmit.bind(this); 18 } 19 20 componentDidMount() { 21 axios 22 .get(`http://192.168.99.100:3001/api/v1/posts/${this.props.match.params.id}`) 23 .then((results) => { 24 console.log(results); 25 this.setState({ post: results.data, title: results.data.title, content: results.data.content}); 26 }) 27 .catch((data) =>{ 28 console.log(data); 29 return(<h1>not found(404)</h1>); 30 }); 31 } 32 33 handleChange = title => event => { 34 this.setState({title: event.target.value}); 35 }; 36 37 handleContentChange = content => event => { 38 this.setState({content: event.target.value}); 39 }; 40 41 handleSubmit = () => { 42 const titleUpdate = update(this.state.post, {title: {$set: this.state.title}}) 43 console.log('title update') 44 console.log(titleUpdate) 45 46 const contentUpdate = update(titleUpdate, {content: {$set: this.state.content}}) 47 console.log('content update') 48 console.log(contentUpdate) 49 50 this.setState({post: contentUpdate}) 51 console.log('state set') 52 console.log(this.state.post) 53 54 console.log('this post id') 55 console.log(this.props.match.params.id) 56 57 this.props.updatePost(this.props.match.params.id, this.state.post) 58 } 59 60 render(){ 61 return ( 62 <div> 63 <form noValidate autoComplete="off"> 64 <TextField 65 id="standard-full-width" 66 label="Title" 67 onChange={this.handleChange('title')} 68 fullWidth 69 margin="normal" 70 variant="outlined" 71 value={this.state.title} 72 /> 73 <hr /> 74 <br /> 75 <TextField 76 id="outlined-multiline-static" 77 label="Content" 78 multiline 79 rows="30" 80 fullWidth 81 onChange={this.handleContentChange('content')} 82 margin="normal" 83 variant="outlined" 84 value={this.state.content} 85 /> 86 </form> 87 <Button variant="contained" onClick={this.handleSubmit}> 88 submit 89 </Button> 90 </div> 91 ); 92 } 93} 94 95export default Form;

"this.props.updatePost"は投稿したデータを更新するメソッドです

試したこと

コンソールに逐一出力して値を確認してみたところ、"titleUpdate",#contentUpdate"は正常に定義されているようなのですが、setStateしてもPostが変更されていないようです。

補足情報(FW/ツールのバージョンなど)

react: 16.9.0
react-addons-update: 15.6.2
material-ui: 4.4.0

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

こんにちは

ご質問に挙げられているソースコードの以下の部分(※console.logは省略しました。)

修正前:

javascript

1this.setState({post: contentUpdate}) 2 3this.props.updatePost(this.props.match.params.id, this.state.post)

で、 updatePostthis.setState によって this.state の内容が変更された後に呼ばれることを意図しているものと思われますが、この前後関係を担保するには、setState の第2引数にコールバックを与えて、そこで(変更後想定の) this.stateを使うコードを書けばよいかと思います。

したがって、以下のように修正してみると、いかがでしょうか?

修正後:

javascript

1this.setState( 2 { post: contentUpdate }, 3 () => { 4 this.props.updatePost(this.props.match.params.id, this.state.post) 5 } 6)

以下もご参考まで

  • react公式ドキュメントの setState の説明からの引用:

setState(object nextState[, function callback])

・・・ In addition, you can supply an optional callback function that is executed once setState is completed and the component is re-rendered.

投稿2019/09/09 01:55

jun68ykt

総合スコア9058

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

wisheebell

2019/09/09 02:06

なるほど。 そのような書き方もできるんですね 参考になります
guest

0

ベストアンサー

this.setState非同期で実行されますので、直後の行ではまだstateは変更されません。

stateを参照せずに、変更に使った値をそのまま使うようにしましょう。

投稿2019/09/09 00:55

maisumakun

総合スコア145973

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

wisheebell

2019/09/09 02:07

ありがとうございます 解決しました
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問