質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.48%
Redux

Reduxは、JavaScriptアプリケーションの状態を管理するためのオープンソースライブラリです。ReactやAngularで一般的にユーザーインターフェイスの構築に利用されます。

JavaScript

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

React.js

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

Q&A

解決済

2回答

2765閲覧

React+Reduxでデータベースに保存していた内容を更新する時方法

退会済みユーザー

退会済みユーザー

総合スコア0

Redux

Reduxは、JavaScriptアプリケーションの状態を管理するためのオープンソースライブラリです。ReactやAngularで一般的にユーザーインターフェイスの構築に利用されます。

JavaScript

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

React.js

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

0グッド

1クリップ

投稿2019/08/07 07:12

初めて投稿します。
まだ勉強中の身ゆえ、考え方間違っていたら、申し訳ないです。

現在React + Reduxで予めデータベースに保存済みの情報をformの各inputのvalueにpropsで表示しています。

今回やりたいことは、データベースの更新時の動作です。

例えば、全てのInputが更新される場合は、よくあるonChangeメソッドを定義すれば、実際にデータベースに値を送るときにthis.stateの内容を送るデータとして使えますが、もし、特定のinputのみデータが変更され、他のinputは変更されない場合は何もしてない方のinputに対してはもちろんonChangeが発火しないので、この方法だとnullの状態で送信してしまいます。

前提・実現したいこと

そこで、inputのvalueを、propsから引っ張ってきたデータで表示しつつ、もし、valueが変更されない場合は、変更してないvalueをstateにセットしたいのですが、どのような方法が最適なのでしょうか?

以下のソースコードの場合ですと、inputのnameがnameは変更せずに、ユーザーはnicknameのみを変更したとします。

すると挙動が、{name: null, nickname: atarashi-nickname}となります。

よろしくご教授お願いします。

該当のソースコード

javascript

1 2class Formdesu extends Component{ 3 constructor(props){ 4 super(props); 5 6 this.state = {name: null, nickname: null}; 7 this.handleChange = this.handleChange.bind(this); 8 this.handleSubmit = this.handleSubmit.bind(this); 9 } 10 11 // このメソッドは変更が加えられ場合にのみステートを変更出来る 12 handleChange(e) { 13 this.setState({ [e.target.name]: e.target.value}); 14 } 15 16 handleSubmit(e) { 17 e.preventDefault(); 18 19 const data = JSON.stringfy(this.state); 20 21 // 以下 post... 22 } 23 24 render(){ 25 <form onSubmit={this.handleSubmit}> 26 <input name="name" value={this.props.default_data[0]['namae'] onChange={this.handleChange}> 27 <input name="nickname" value={this.props.default_data[0]['nickname'] onChange={this.handleChange}> 28 </form> 29 } 30} 31

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

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

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

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

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

guest

回答2

0

ベストアンサー

こんにちは

ご質問にあるコードを拝読しますと、入力された name や nickname の値は、redux の state に保存されるわけではなく、 フォームコンポーネントのthis.state に入れておくようですので、いったん Redux の利用は検討から外しました。

その上で、ご質問のような、フォームからの入力によって変更されたものだけをサーバーに送りたい場合は、サーバーから受け取った時点での値を、編集中の値とは別に保持しておけばよいかと思います。具体的には、フォームコンポーネントの this.state の初期値を

javascript

1 this.state = { 2 orig: { name: '', nickname: '' }, 3 form: { name: '', nickname: '' } 4 };

のように作っておいて、 orig のほうはサーバーから受け取った値を入れたらその後は変更しないでおきます。 form のほうはユーザーの入力値で変更していきます。これによって、変更後と変更前を比較することができるようになります。

以下は上記を使用したサンプルです。

html

1<div id="app"></div>

jsx

1class Form extends React.Component { 2 constructor(props) { 3 super(props); 4 5 this.state = { 6 orig: { name: '', nickname: '' }, 7 form: { name: '', nickname: '' } 8 }; 9 10 this.handleChange = this.handleChange.bind(this); 11 this.handleSubmit = this.handleSubmit.bind(this); 12 } 13 14 componentDidMount() { 15 fetch('https://demo2746340.mockable.io/q204849') 16 .then(res => res.json()) 17 .then(data => { 18 this.setState({ orig: {...data}, form: {...data}}); 19 }); 20 } 21 22 handleChange(e) { 23 const form = { ...this.state.form, [e.target.name]: e.target.value }; 24 this.setState({ form }); 25 } 26 27 handleSubmit(e) { 28 // 変更されているパラメータを持つオブジェクトを作成 29 const { form, orig } = this.state; 30 const params = _.omitBy(form, (v, k) => orig[k] === v); 31 32 alert(JSON.stringify(params)); 33 } 34 35 unchanged() { 36 const { form, orig } = this.state; 37 return ['name', 'nickname'].every(k => form[k] === orig[k]); 38 } 39 40 render() { 41 const { name, nickname } = this.state.form; 42 return ( 43 <div className="container"> 44 <p>name:&nbsp; 45 <input name="name" value={name} onChange={this.handleChange} /> 46 </p> 47 <p>nickname:&nbsp; 48 <input name="nickname" value={nickname} onChange={this.handleChange} /> 49 </p> 50 <p> 51 <button onClick={this.handleSubmit} disabled={this.unchanged()}>送信</button> 52 </p> 53 </div> 54 ); 55 } 56} 57 58 59ReactDOM.render(<Form />, document.querySelector("#app"));

上記のコードを、jsFiddle にも上げておきました。

このサンプルでは、

  • componentDidMount の中で、現在のDBに保存されている値を取ってくる想定で、APIのダミーを fetch して、そのレスポンスを冒頭に書いたような形で、 setStateします。
  • サーバーから取ってきた元の値から変更がないときは、[送信]ボタンを disabled にします。
  • [送信]ボタンが押されたとき、変更されたプロパティのみを持つオブジェクトを(lodash の omitBy を使って)作成し、これをJSONにして alert で表示させています。

以上、参考になれば幸いです。

投稿2019/08/07 15:47

jun68ykt

総合スコア9058

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

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

退会済みユーザー

退会済みユーザー

2019/08/09 19:46

お教えいただいた比較する方法で無事できました。ありがとうございました。
jun68ykt

2019/08/10 03:37

どういたしまして。 > 無事できました。 とのことで、よかったです ????
退会済みユーザー

退会済みユーザー

2019/08/10 06:01

はい。勉強になりました???? また、何かあったらよろしくお願いします????
guest

0

componentDidMount などでサーバーのAPIを叩いて編集対象のレコードを取得し、初期値としてセットすれば良いと思います。

投稿2019/08/07 07:26

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問