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

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

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

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

Q&A

解決済

2回答

1783閲覧

Reactで配列のstateを変更しても再描画されない

te_ff

総合スコア13

React.js

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

0グッド

0クリップ

投稿2021/03/29 09:28

前提・実現したいこと

Reactで動画を複数個登録できる動的フォームを作成しております。
動画にチェックボックスを用意しているのですがstateを更新しても、再描画がされません。
チェックボックスを押下後、再度同じチェックボックスを押下すると反映されるのですが、原因を教えていただきたいです。
stateは新しいインスタンスを作成し、反映されないとのことで下記を参考にしてみたのですが解決しませんでした。
https://teratail.com/questions/305000

該当のソースコード

React.js

1export const VideoRelationForm = (prop) => { 2 const initialVideoState = { 3 'video': '', 4 'valid_flg': false, 5 } 6 const [title, setTitle] = useState(""); 7 const [video, setVideo] = useState([initialVideoState]); 8 9 const handleSubmit = (e) => { 10 e.preventDefault(); 11 12 const formData = new FormData(); 13 formData.append('title', title); 14 video.map(v => { 15 formData.append('video', v.video, v.video.name); 16 formData.append('valid_flg', v.valid_flg); 17 }); 18 19 // API通信 20 } 21 22 const AddForm = (e) => { 23 e.preventDefault(); 24 setVideo([...video, initialVideoState]); 25 } 26 27 const handleChange = (hogehoge, e) => { 28 e.preventDefault(); 29 var newVideo = [...video]; 30 newVideo.find(v => v===hogehoge).valid_flg= e.target.checked; 31 setVideo(newVideo); 32 } 33 34 return( 35 <label> 36 タイトル: 37 <input type="text" name="title" value={ title } onChange={ (e) => setTitle(e.target.value) } /> 38 </label> 39 {video.map(v => 40 <> 41 <label> 42 動画: 43 <input type="file" name="video" accept='video/*' alt="動画" /> 44 </label> 45 <label> 46 動画タイプ: 47 <input type="checkbox" name="valid_flg" onChange={ (e) => handleChange(v, e) } checked={v.valid_flg} /> 48 </label> 49 </> 50 )} 51 ) 52}

試したこと

結果変わらず

const handleChange = (hogehoge, e) => { e.preventDefault(); var newVideo = []; video.map( v => { if(v===hogehoge){ v.valid_flg = e.target.checked; } newVideo.push(v); }); setVideo(newVideo); }

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

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

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

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

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

hoshi-takanori

2021/03/29 17:43

handleChange の中で newVideo.find(v => v===hogehoge).valid_flg= e.target.checked としていますが、これだと既存のオブジェクトを書き換えてしまいますね。
te_ff

2021/03/30 01:12

ありがとうございます! どのように対応すれば再描画されるかわかりますでしょうか?
hoshi-takanori

2021/03/30 01:31

その行を newVideo = video.map(v => v === hogehoge ? { ...v, valid_flg: e.target.checked } : v); と書き換える、かなぁ。
guest

回答2

0

自己解決

HandleChangeにて
e.preventDefault();
を記載していることにより、動作がおかしくなっていたようです。

const handleChange = (hogehoge, e) => { var newVideo = [...video]; newVideo.find(v => v===hogehoge).three_dimensional_flg = e.target.checked; setVideo(newVideo); }

で解決しました。

投稿2021/03/30 01:24

te_ff

総合スコア13

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

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

0

配列をmapする場合は、keyを指定しましょう。

jsx

1 {video.map(v => 2 <Fragment key={v}> 3 <label> 4 動画: 5 <input type="file" name="video" accept='video/*' alt="動画" /> 6 </label> 7 <label> 8 動画タイプ: 9 <input type="checkbox" name="valid_flg" onChange={ (e) => handleChange(v, e) } checked={v.valid_flg} /> 10 </label> 11 </Fragment> 12 )}

投稿2021/03/29 09:31

maisumakun

総合スコア145183

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

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

maisumakun

2021/03/29 09:31

本題ではありませんが、<input type="file">の中身の問題は大丈夫でしょうか?
te_ff

2021/03/29 09:57

ありがとうございます! keyを指定してみたのですが、結果変わりませんでした。 fileの中身に関してはまだ試していませんが、fileにvalueで値指定はできないため、onChangeのみで対応しようかと思っています。 ただ、出力している項目に関してはstateで管理したほうがいいかと思いますのでcheckboxに関してはstateで管理できればと考えております。
maisumakun

2021/03/29 09:58

ブラウザコンソールになにかメッセージが出ていたりはしませんか?
te_ff

2021/03/29 10:21 編集

要素を追加した際にFragmentのKeyが[object Object]となっているためエラーとなっておりました。 ただ、要素を一つも追加していない(要素が一つ)時にも同様の動きが発生しているため特に関係はないかと思っております。 また、mapで戻り値がないためWARNINGが表示されていたため、 https://www.javaer101.com/en/article/27207646.html こちらを参考に ``` {video.map(v => ( ))} ``` としてみたのですが結果変わらずでした。。。 要素を追加した際のエラー ``` Warning: Encountered two children with the same key, `[object Object]`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version. ```
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問