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

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

新規登録して質問してみよう
ただいま回答率
85.35%
Next.js

Next.jsは、Reactを用いたサーバサイドレンダリングなどを行う軽量なフレームワークです。Zeit社が開発しており、nextコマンドでプロジェクトを作成することにより、開発環境整備が整った環境が即時に作成できます。

JavaScript

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

React.js

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

Q&A

解決済

1回答

2006閲覧

動的に追加したコンポーネント内で入力した値を、すべて親側で受け取りたい

tksx1227

総合スコア6

Next.js

Next.jsは、Reactを用いたサーバサイドレンダリングなどを行う軽量なフレームワークです。Zeit社が開発しており、nextコマンドでプロジェクトを作成することにより、開発環境整備が整った環境が即時に作成できます。

JavaScript

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

React.js

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

0グッド

0クリップ

投稿2021/07/05 10:06

編集2021/07/05 10:12

前提・実現したいこと

少々複雑になってしまいましたが、タイトル通りのことを実装したいです。

元のプログラムはごちゃごちゃしているため、該当する部分の最小限のコードを載せています。

現在は、親コンポーネント内でuseStateを使い、子コンポーネントにstateを付与することで値を管理しようとしていましたが、動的に追加されたコンポーネントにstateを振ることが困難だと感じ、相談するに至りました。

最終的には、logをクリックした際に、以下のようにそれぞれのコンポーネントで入力した値を1つのリストにまとめたものが出力されれば満足です。(リストの要素は動的に増える)

質問等ありましたら随時補足していきますので、どなたか回答よろしくお願いします。

[追記]
やりたいこととしては
・子コンポーネントでinputタグを作成
・親側では動的にの子コンポーネントを増やすことができる
・親側で子コンポーネントで入力された値を取得できる

言ってしまえば、子から親への値の受け渡しに近いのかもしれません。

List = [ { param1: "aaaa", param2: "bbbb", }, { param1: "cccc", param2: "dddd", }, { param1: "eeee", param2: "ffff", }, ]

該当のソースコード

Parent.jsx

Javascript

1export const Parent = () => { 2 const [list, setList] = useState([]); 3 4 const onClick = () => { 5 const newList = [ 6 ...list, 7 { 8 param1: "", // この値を子コンポーネントで埋めたい 9 param2: "", // この値を子コンポーネントで埋めたい 10 }, 11 ]; 12 setList(newList); 13 }; 14 15 const onClickLog = () => { 16 console.log(list) 17 } 18 19 return ( 20 <> 21 {list.map((item, idx) => { 22 // この辺をどう変更すべきかがわからない 23 return <Children key={idx} item={item} />; 24 })} 25 <button onClick={onClick}>追加</button> 26 <button onClick={onClickLog}>log</button> 27 </> 28 ); 29};

Children.jsx

JavaScript

1// このpropsにparam1, param2をセットしたい 2export const Children = (props) => { 3 const [param1, setParam1] = useState(""); 4 const [param2, setParam2] = useState(""); 5 6 const onChange1 = (e) => { 7 setParam1(e.target.value); 8 }; 9 const onChange2 = (e) => { 10 setParam2(e.target.value); 11 }; 12 13 return ( 14 <> 15 <input value={param1} onChange={onChange1} /> 16 <input value={param2} onChange={onChange2} /> 17 </> 18 ); 19};

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

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

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

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

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

guest

回答1

0

ベストアンサー

とりあえずこんな感じでいかがでしょうか。
(なお、ひとつの子コンポーネントはひとつの item を表示するので、単数形 Child の方がいいと思います。)

diff

1 export const Parent = () => { 2 const [list, setList] = useState([]); 3 4 // 略 5 6+ const setItem = (idx, item) => { 7+ const newList = [...list]; 8+ newList[idx] = item; 9+ setList(newList); 10+ }; 11+ 12 return ( 13 <> 14 {list.map((item, idx) => { 15 // この辺をどう変更すべきかがわからない 16- return <Children key={idx} item={item} />; 17+ return <Child key={idx} item={item} setItem={(item) => setItem(idx, item)} />; 18 })} 19 <button onClick={onClick}>追加</button> 20 <button onClick={onClickLog}>log</button> 21 </> 22 ); 23 };

diff

1-export const Children = (props) => { 2- const [param1, setParam1] = useState(""); 3- const [param2, setParam2] = useState(""); 4+export const Child = ({ item, setItem }) => { 5 6 const onChange1 = (e) => { 7- setParam1(e.target.value); 8+ setItem({ ...item, param1: e.target.value }); 9 }; 10 const onChange2 = (e) => { 11- setParam2(e.target.value); 12+ setItem({ ...item, param2: e.target.value }); 13 }; 14 15 return ( 16 <> 17- <input value={param1} onChange={onChange1} /> 18- <input value={param2} onChange={onChange2} /> 19+ <input value={item.param1} onChange={onChange1} /> 20+ <input value={item.param2} onChange={onChange2} /> 21 </> 22 ); 23 };

投稿2021/07/05 23:02

hoshi-takanori

総合スコア7901

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

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

tksx1227

2021/07/06 00:33

回答ありがとうございます! こちらのコードを参考にしてみたところ、期待していた挙動をしてくれました! 特に以下のように、propsに渡す関数に引数を設定する記述方法のことをすっかり忘れており、大変参考になりました。 <Child key={idx} item={item} setItem={(item) => setItem(idx, item)} /> 追加で少しお聞きしたいのですが、上記のプログラムに、動的に要素を削除する機能を付与した場合、keyはidxを使ったままで大丈夫なのでしょうか。 例えば、追加や削除を繰り返すことで、keyが3のコンポーネントがコロコロ変わる(keyが一意の要素を指さない)と思うのですが、入力情報が本来の値とズレるといったことは起こり得ますかね。
hoshi-takanori

2021/07/06 00:45

確かに、key={idx} だとずれますね。ただ、param1 や param2 の値も書き換わるので、結果的にはうまく動いてるように見えると思いますが、できれば uuid などを使って一意かつ不変な id を設定するのが好ましいと思います。 また、Child に渡す setItem 関数は毎回すべて作り直されて更新範囲が大きくなるので、うまくメモ化した方が良いかもしれません…。
tksx1227

2021/07/06 00:55

なるほど、uuidというものがあるのですね。 是非取り入れてみます。 メモ化についても、後々最適化する際に考慮したいと思います。 追加対応まで本当にありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問