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

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

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

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

React.js

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

Q&A

解決済

1回答

939閲覧

[React] formと上手く付き合えない!

uk_63

総合スコア29

JavaScript

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

React.js

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

0グッド

1クリップ

投稿2019/01/06 12:54

#はじめに
私の質問を見ていただいてありがとうございます。

React初心者です。
練習としてTodoアプリを作ってみました。
そこで疑問に思ったことがあります。

質問に答えていただけたら幸いです。

#[Q.1]formを作成すれば、stateをもつコンポーネントが増える?

・親コンポーネントでstate管理。(一極集中でデータを管理)
・子コンポーネントではpropsでデータを受けて表示させる。(あくまでデータの受け皿として、受けたデータを反映させるのみ)

私は書籍や記事から上記のように書くことが望ましいと理解しました。

しかし、子コンポーネントのformを作成すると親コンポーネントのstateを変更するためにstateを持つ子コンポーネントのformを増やさなければなりません。

####form作成のたびにstateを作成してバラけるのは、仕方がないことでしょうか?また、解決方法は、ありますか?

#[Q.2]配列へのデータの追加方法として最適な方法は?

現在は、下記のように配列に追加をしてます。

js

1// 初期値は、 objects: [] 2const newObject = this.state.objects.slice(); 3 4newObjet.push({ 5 objectContent: newObjectContent 6}); 7 8this.state({ newObject });

####他に配列へのデータ追加方法にいい方法があれば教えて頂きたいです。

#[Q.3]stateの初期値はカラの配列にして、formのnameでデータの種類を分けるのが良い?

stateの初期値は空っぽの配列にして、formのnameで指定したデータをevent.target.***.valueで取得し、定数の中に入れて、それを.push()で追加、setStateしていました。

####初期値の配列を入れ子にする方がいいですか??
下記のような書き方です。
以前これでコードを書こうとしましたが、これだと配列の中身の取り出し方が難しく現在の手法にしました。

js

1this.state = { 2 objects: [ 3 {id: "", content: ""} 4 ] 5}

#最後に
最後まで読んでくださってありがとうございます。
質問の仕方もわかりにくかったり、間違っているかもしれませんが、ご回答宜しくお願いします。

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

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

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

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

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

guest

回答1

0

ベストアンサー

こんにちは。

以下にて、各質問に順に回答していきます。

[Q.1]formを作成すれば、stateをもつコンポーネントが増える?

・親コンポーネントでstate管理。(一極集中でデータを管理)
・子コンポーネントではpropsでデータを受けて表示させる。(あくまでデータの受け皿として、受けたデータを反映させるのみ)

私は書籍や記事から上記のように書くことが望ましいと理解しました。

はい。その理解で概ね問題ないです。

form作成のたびにstateを作成してバラけるのは、仕方がないことでしょうか?また、解決方法は、ありますか?

については、

  • 入力フォームとなる子コンポーネントにstateを持たせずに、
  • 親コンポーネントのstateに子であるフォームからの入力値を持たせ、
  • フォームに配置される(<input /><textarea />などの)入力要素のonChangeハンドラを親のメソッドとして持たせ、子にprops経由で渡す

ことで解決できます。

例としては、ひとつ後のご質問に対する私からの回答として挙げたコードでは、入力フォームとなるTodoInputを、stateを持たないFunctional Component にしています。

方針としては、

  • stateはなるべく親コンポーネントのほうに寄せ、子コンポーネントは表示やユーザー入力を受け取るだけのもの(Presentational Component)とする。親コンポーネントは、そのような子コンポーネントを一つ以上含む、入れ物(Container Component)と考える

ようにします。そうすると、

  • 親側のほうに Class Component が集まり、枝葉に行くほど Functional Componentが多くなる(はず)

ということになります。

参考までに、以下は、Presentational ComponentとContainer Component、および Functional ComponentとClass Component の説明として検索上位に出てくる記事です。(すでにお読みになっていたら、すみません。)

  

[Q.2]配列へのデータの追加方法として最適な方法は?

たとえば、以下のようなstate

javascript

1this.state = { tasks: [] }

があったときに、this.state.tasks の先頭に newTask を追加した配列で setState するには

javascript

1this.setState({ tasks: [newTask, ...this.state.tasks] });

とすればよいです。
ひとつ後のご質問に対する私からの回答のコードでも、以下にてこれを使っています。

ちなみに末尾に追加であれば、以下です。

javascript

1this.setState({ tasks: [...this.state.tasks, newTask] });

...によるスプレッド構文 は、配列およびオブジェクトの展開ともに、現在のstateから次のstateを作るときによく使います。ひとつ後のご質問に対する私からの回答のコードで、オブジェクトに対して ...を使って setStateしている部分が以下です。

[Q.3]stateの初期値はカラの配列にして、formのnameでデータの種類を分けるのが良い?

空の配列でよいと思います。

javascript

1this.state = { 2 objects: [ 3 {id: "", content: ""}, 4 ] 5}

の考え方だと、ひとつ後のご質問の App のstate も

javascript

1this.state = { 2 tasks: [ 3 { title: "", description: "" }, 4 ] 5}

のようになり、このtasksの末尾の要素 { title: "", description: "" } をフォームからの入力に紐づけようという意図だったものと思いますが、ちょっと分かりにくいコードになってしまうかなと思います。フォームからの入力は、state の中の別プロパティに持たせたほうが分かりやすいです。なので

stateの初期値はカラの配列

で問題ないと思います。

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

投稿2019/01/06 16:22

編集2019/01/07 03:11
jun68ykt

総合スコア9058

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

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

uk_63

2019/01/07 00:02

丁寧なご回答ありがとうございます。 疑問が解消されました。Reactの勉強をさらにすすめていきたいと思います。
jun68ykt

2019/01/07 00:59

どういたしまして。 > 疑問が解消されました。 とのことで、よかったです????
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問