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

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

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

React Nativeは、ネイティブモバイルアプリ(iOS/Android)を作成できるJavaScriptフレームワークです。Reactと同じ設計のため、宣言的なコンポーネントでリッチなUIを開発することが可能です。

JavaScript

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

React.js

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

Q&A

解決済

2回答

452閲覧

setStateをA:[{B:aa,C:a},{B:bb,C:b},{B:cc,C:c}]のkey=0,1,2でそれぞれで行うには??

MOTOMUR

総合スコア195

React Native

React Nativeは、ネイティブモバイルアプリ(iOS/Android)を作成できるJavaScriptフレームワークです。Reactと同じ設計のため、宣言的なコンポーネントでリッチなUIを開発することが可能です。

JavaScript

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

React.js

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

0グッド

0クリップ

投稿2018/03/01 08:51

編集2018/03/10 14:05

mapでstateによって繰り返し描画をしているとします。

例えば。

js

1this.state = { 2 Items:['0','1','2'], 3 refers:[{message:yeah},{message:hey},{message:awsome}] 4}

のようなstateがあり、inputにより、中身を参照し、中身を変更したいとします。

イメージ的にこうやって書けばできると思って、下のように描いて見ました。

js

1<List> 2 { 3 this.state.Items.map( 4 key => { 5   <ListItem> 6 <input onChangeText={(input) => this.setState({refers[key].message:input}) 7 value={this.state.refers[key].message} 8 </ListItem> 9 } 10 ) 11 } 12</List>

これだとうまくsyntax的にできないようなのですね。

なぜこのようなことをしているかと言いますと、
Itemsもinputにより変化して、その各々についてさらにrefersの中身を設定する、といった構造で依存関係になっているからです。
(作成中のコードで困っているのはrefersがさらに他にも内容がある状態ですが、これがわかれば同じだと思っているので、この質問としています。)

このような場合、どのように対処するのが正しいでしょうか?
このやり方は間違っていますでしょうか?

コード追記

(settingTime, key) => { 〜〜〜〜〜〜〜〜〜〜〜〜〜  <Input   style={{marginTop:-15}}   onChangeText={(input) => this.handleInputChange_S_H(input,key).bind(this)}   value={(this.state.komaTime[key] !== undefined) ? this.state.komaTime[key].START_HOUR : ''}/>  handleInputChange_S_H = (input,key) => {   const newKomaTime = update(this.state.komaTime, {[key]: {START_HOUR: {$set: input}}})   this.setState({komaTime: newKomaTime})  }

追加質問

immutabilityな記述をmapのなかで。

js

1var keys = [ [0,0], [0,1] ] 2keys.map( 3 key => { 4 var keyWhatDay = key[0] 5 var keyWhatTime = key[1] 6 var newSchedule = update(this.state.schedule, { [keyWhatDay] : { [keyWhatTime] : { STATUS : { $set: true }, ID : { $set: ID } } } }) 7 8 this.setState({schedule:newSchedule}) 9 } 10)

このような記述が必要であった場合、mapとupdateの相性はよくないように見えるのですが、どうなのでしょうか。
現在の書き方だと、scheduleを更新することはできません。
keysは変動するので、map以外の方法は思いつかなかったです。
どのようにしたらうまく動作させられるのでしょうか。

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

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

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

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

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

guest

回答2

0

ベストアンサー

Itemsの必要性がよく分からないので使わない方向で回答しますと、
配列の1要素を変更する必要がありますが、stateをmutateしてはいけないのでコピーする必要があります。
公式?のimmutability-helperを使えば楽です。

DEMO(Codesandbox)
(React NativeではなくReactの例です)

inputに変更があったとき、event object eだけでなくインデックスiもイベントハンドラーに渡します。

js

1 {this.state.messages.map((m, i) => 2 <input type="text" onChange={e => this.handleInputChange(e, i)} 3 value={m.message} key={i}/> 4 )}

そしてイベントハンドラーでは配列state.messagesのインデックスiの要素を更新します。

js

1 handleInputChange = (e, i) => { 2 const newMessages = update(this.state.messages, {[i]: {message: {$set: e.target.value}}}) 3 this.setState({messages: newMessages}) 4 }

投稿2018/03/02 06:24

karamarimo

総合スコア2551

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

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

MOTOMUR

2018/03/02 10:13

回答ありがとうございます。お久しぶりです。 Itemsというのは、僕の開発状態に近づけるために説明に無理やり付加したものです。 本来のものでの壁となったのは、 ユーザーが決めたItemsの個数それぞれに、Inputで入力してもらう必要があったので、 Itemsがその時の個数(key)としてInputを作成し、入力させたかったからです。 なるほど、onChangeTextで直接setStateせずに、関数を挟んで、immutability-helperを使ってupdateしてsetStateするといったやり方ですね。 もしreact-nativeにてimmutability-helperを使用できなかった場合は、 下記のようにコピーして改変して、setStateすれば良いということですね? handleInputChange = (e, i) => { const PreMessages = this.state.messages PreMessages[ i ].message =e.target.value this.setState({messages: PreMessages}) }
MOTOMUR

2018/03/02 10:20

それと、勉強不足でわからないので質問なのですが、 map内のarrowの引数(ここでいう ( m, i ) => ) は一つ目はmapされた値で、二つ目はkeyが入るんでしょうか?そのように受け止めましたが、あってますでしょうか? それと、$set: e.target.valueはimmutability-helperの何かですかね?
karamarimo

2018/03/02 10:46 編集

> ユーザーが決めたItemsの個数それぞれに、Inputで入力してもらう必要があったので、 Itemsがその時の個数(key)としてInputを作成し、入力させたかったからです。 ユーザーが決めた個数だけrefersの要素数を増減させれば、Itemsは不要ではないでしょうか。 immutability-helperは単にjsのオブジェクトを扱うライブラリなのでreact nativeでも使用できると思います。 > PreMessages[ i ].message =e.target.value それだと state を mutate しているのでよくありません。 > 一つ目はmapされた値で、二つ目はkeyが入るんでしょうか? 1つ目は各要素の値、2つ目は各要素のインデックスです。 > $set: e.target.valueはimmutability-helperの何かですかね? $setはそうです。documentationを見てください。 react nativeでは e.target.value ではないと思います。
MOTOMUR

2018/03/02 11:39

>ユーザーが決めた個数だけrefersの要素数を増減させれば、Itemsは不要ではないでしょうか。 個数といっても、数字で選ぶのではなく、他の要素として得たものそれぞれに対して値を入れるという処理だったので、Itemsを使っておりました。 もしかしたら、プロジェクトでは無駄な要素になってしまっているかもしれませんが。 >immutability-helperは単にjsのオブジェクトを扱うライブラリなのでreact nativeでも使用できると思います。 なるほど、ありがとうございます。 上での不明点は解消されました、ありがとうございます。 別の不明部分があるのですが、mutateとはstateの配列の一部を変更しようとしているという 解釈で良いでしょうか? refers:[ {item:1},{item:2},{item:3} ] というものがあったとして、 this,state.refers[ i ].name = "dog" というものもmutateしているのでしょうか? この場合は、もしmutateしていて、回避するためには const newRefers = update(this.state.refers, {[i]: {name: {$set: e.target.value}}}) としてsetStateしたらいいのでしょうか? 回りくどい質問の仕方になってしまいましたね。 配列のようにstateの一部を改変するためにはmutate回避する必要があり、immutability-helperのupdateで一部変えてsetStateをすることで、配列と同じようにstateの一部を改変できるという解釈であってますか!!?
karamarimo

2018/03/02 12:16

> this.state.refers[ i ].name = "dog" というものもmutateしているのでしょうか? はいそうです。 mutateというのは配列などのコレクション的なデータ構造で一部を変更(上書き)することです。 変更すると、その配列などのオブジェクトを参照している所すべてに影響がでます。 参照、ポインタ、immutableの概念をご存じないのでしたら調べてみてください。 reactでは直接stateを上書きするのは推奨されておらず、新しいデータを setState で与えることで state を更新します。 immutability-helper の update は 上書きせずに新しいオブジェクトを生成します。 (上書き保存と名前を付けて保存の違いみたいなものです) 使い方は documentation を見てください。 > 配列のようにstateの一部を改変するためにはmutate回避する必要があり、immutability-helperのupdateで一部変えてsetStateをすることで、配列と同じようにstateの一部を改変できるという解釈であってますか!!? 「配列と同じようにstateの一部を改変できる」の意味がよく分かりませんがたぶんそういうことです。
MOTOMUR

2018/03/02 12:41

>「配列と同じようにstateの一部を改変できる」の意味がよく分かりませんがたぶんそういうことです。 上述の内容で理解できました。「配列と同じようにstateの一部を改変できる」は変なこと言ってましたね。 ありがとうございます。 ところで申し訳ないのですが、自分の理解した通りに記述して動作を見ていてのですが、 Inputに書き込もうとtapすると undefined is not an object( evaluating 'object[key]') となってしまいます。 (settingTime, key) => { 〜〜〜〜〜〜〜〜〜〜〜〜〜 <Input style={{marginTop:-15}} onChangeText={(input) => this.handleInputChange_S_H(input,key).bind(this)} value={(this.state.komaTime[key] !== undefined) ? this.state.komaTime[key].START_HOUR : ''}/> handleInputChange_S_H = (input,key) => { const newKomaTime = update(this.state.komatime, {[key]: {START_HOUR: {$set: input}}}) this.setState({komaTime: newKomaTime}) }
karamarimo

2018/03/02 13:59

質問文の方に追記してください。 this.state.komaTime[key] のところでエラーになっていないでしょうか。 つまり komaTime が undefined になっていないでしょうか。
MOTOMUR

2018/03/03 06:17

komaTimeはundefinedかもしれません。 Inputにて入力されて初めて中身が存在するので。 this.state={komatime:[]}はありますが。。 質問文に追記しますね。
MOTOMUR

2018/03/03 06:20

バカだったことに気づきました。 update内のkamatimeがtがuppercaseになってませんでした。。
MOTOMUR

2018/03/03 06:21

しかし、それを直しても同じエラーのままでした。
karamarimo

2018/03/03 10:36

.bind(this) はいらないと思います。 どの行でエラーが出ていますか?
MOTOMUR

2018/03/03 17:10

handleChangeの const newKomaTime = update(this.state.komatime, {[key]: {START_HOUR: {$set: input}}}) の部分です。
karamarimo

2018/03/04 05:09

komatime か komaTime か分かりませんが undefined になっていないでしょうか。
MOTOMUR

2018/03/04 06:13

this.state={ komaTime:[] } としていますね。 T大文字ですね。
karamarimo

2018/03/04 11:38

今の場合START_HOURプロパティが存在しないのでエラーになっているようです。 入力されて始めて値を作るのではなく初期値を設定したほうがいいと思います。
MOTOMUR

2018/03/04 14:57

なるほど。そういう問題でしたか。思いつきませんでした。試してみますね。
MOTOMUR

2018/03/05 15:34

試したらうまく機能しました。ありがとうございます!
MOTOMUR

2018/03/10 13:59

こんばんは。おかげで順調にコーディングができております。 immutability-helperとmapの組み合わせで困ってしまったので、この場を借りて質問させてください。 var keys = [ [ 0 , 0 ], [ 0 , 1 ] ] keys..map( key => { var keyWhatDay = key[0] var keyWhatTime = key[1] var newSchedule = update(this.state.schedule, { [keyWhatDay] : { [keyWhatTime] : { STATUS : { $set: true }, ID : { $set: ID } } } }) this.setState({schedule:newSchedule}) } ) イメージとしてはこのように書きたかったのですが、scheduleの中身の更新が行えず、困っています。 考えられる理由として、map内でのsetStateによって、immutabilityな処理が行えていないからこのようなことになってしまったのかなと思います。 (keysは変動します。) このような場合どのように記述しますでしょうか?
karamarimo

2018/03/10 14:19

新しく質問を立てたほうがいいと思いますが...。 問題と関係ないですが map ではなく foreach でいいのではないでしょうか。 それ以外は問題ないと思います。
MOTOMUR

2018/03/10 14:25

karamarimoさんに聞きたかったので、流用してしまいました。以後やめておきます。 forEachにしても、やはり問題となる部分があるので、新しく、質問を作成しますので、回答していただけたら嬉しいです。
guest

0

話を単純にすると、親コンポーネントAの子要素として例えばテキストボックスが3つあって、それら3つのテキストボックスの値を親コンポーネントAのstateに反映出来れば良いという話でしょうか?(親コンポーネントのstateで、子要素のテキストボックス毎の入力値を配列であれオブジェクトであれ把握できれば良いみたいな?)

追記

refers[key].Item1でItem1の中身を参照できるのかということです。

さらに[]でkey側を囲ってあげる必要があります。

const refers = [ {item1: 'aaa'}, {item2: 'bbb'} ]; const key = 0; const obj = { [refers[key].item1]: 'xxx' //[]でkeyを囲む }

ただ、上の場合、[refers[key].item1]は'aaa'になるので、やりたいこととは異なる感じですよね?

複雑な部分では、setStateでstateの配列部分の一部の変更を可能なのかということで、不可能であればこのようなことをしたい場合、どのように対処していますか?

たぶん、明日、自分ならこうするといったやり方を題材を単純化して追記します。

投稿2018/03/01 10:25

編集2018/03/01 11:47
HayatoKamono

総合スコア2415

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

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

MOTOMUR

2018/03/01 11:22 編集

僕のプロジェクトでは、下記のような配列stateの中身で管理したいのです。 refers:[ {item1:aaa ,item2:bbb}, {item1:ccc ,item2:ddd}, ] この場合、key=0、1に対してitem1とitem2を取り出せますよね?(ここも不安なのですが。) 聞きたいことを簡潔にまとめると、 配列型のstateの中身をkey毎にsetStateで変化、保持させたいということです。 僕のコードイメージ的には key => { return( <Input onChangeText={(input) => this.setState( { refers[key].Item1 : input } } ) /> <Input onChangeText={(input) => this.setState( { refers[key].Item2 : input } } ) /> ) } このようになりました。なぜならインプットがstateの中身をレスポンシブに表示、保持するという特性上、これ以外の対処が僕には見つけられなかったからです。 しかし、setStateでこのように指定の配列場所にstateを保存させることができるのかということは、僕の知りうる限りは、できないと思ったので質問させていただきました。
MOTOMUR

2018/03/01 11:25

簡単な質問で不安な部分は、 refers[key].Item1でItem1の中身を参照できるのかということです。 複雑な部分では、 setStateでstateの配列部分の一部の変更を可能なのかということで、 不可能であればこのようなことをしたい場合、どのように対処していますか? といった質問でした。 わかりづらい質問で申し訳ありません。
MOTOMUR

2018/03/01 12:11

そうですね。 keyを使わない場合だと、 (例えば、refer:{item:aaa,item2:bbb}なら) setState({ refers: { item: input } }) とすれば良いと思うのですが、keyが入ってくると難しいですね。 回答ありがとうございます。よろしくお願いします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問