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

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

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

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

Q&A

解決済

2回答

812閲覧

【React】Object.assign({},)を使ってオブジェクトの値を変更してもレンダリングされずチェックボックスが変わらない

nakamu

総合スコア82

React.js

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

0グッド

0クリップ

投稿2020/10/21 01:01

onChangeに直接書いたりreturnの中でmapを使ってループさせる書き方など試してみましたがうまくいきません。

React

1import React, { useEffect, useState, useContext } from "react"; 2import { useHistory } from 'react-router-dom'; 3import { storage, db } from "../firebase.js"; 4 5const SelectBan = () => { 6 7 const [rulFlg, setRulFlg] = useState({}); 8 const [rul, setRul] = useState([]); 9 10 useEffect(() => { 11 const docRef = db.collection("terBn").orderBy("index"); 12 docRef.get().then((querySnapshot) => { 13 querySnapshot.forEach((doc) => { 14 let data = doc.data(); 15 rulFlg[doc.id] = data.default; 16 17 setRules(oldForm => [...oldForm, 18 <label className="bnLabel" htmlFor={doc.id} key={doc.id}> 19 <input 20 id={doc.id} 21 type="checkbox" 22 name="bnRules" 23 checked={rulFlg[doc.id]} 24 onChange={handleChange} 25 value={doc.id} 26 /> 27 {data.rule} 28 </label> 29 ]); 30 setRulesFlg(Object.assign({}, rulFlg)) 31 }); 32 }).catch(function(error) { 33 console.log("Error getting document:", error); 34 }); 35 }, []) 36 37 const handleChange = (e) => { 38 // rulFlg[e.target.value]の値はしっかり取れてます 39 rulFlg[e.target.value] = !rulFlg[e.target.value] 40 setRulFlg(Object.assign({}, rulFlg)) 41 } 42 43 const handleSubmit = () => { 44 } 45 46 return ( 47 <div className="selectBan"> 48 <div className="formTitle">アイテムの選択</div> 49 <div className="formCheckbox"> 50 {rul} 51 </div> 52 <button onClick={handleSubmit}>完了</button> 53 </div> 54 ); 55} 56 57export default SelectBan; 58

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

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

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

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

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

guest

回答2

0

自己解決

コードをmapで生成したのとコード用のuseStateを消してuseStateを値用のみしたところうまく作動しました。
詳細はわかりませんが、2つのuseStateがぶつかって再レンダリングができなくなったぽいです。

React

1import React, { useEffect, useState, useContext } from "react"; 2import { useHistory } from 'react-router-dom'; 3import { storage, db } from "../firebase.js"; 4 5const SelectBan = () => { 6 7 const [rulFlg, setRulFlg] = useState({}); 8 9 useEffect(() => { 10 const docRef = db.collection("terBan").orderBy("index"); 11 docRef.get().then((querySnapshot) => { 12 querySnapshot.forEach((doc) => { 13 let data = doc.data(); 14 rulFlg[doc.id] = [data.default, data.rule]; 15 setRulFlg(Object.assign({}, rulFlg)) 16 }); 17 }).catch(function(error) { 18 console.log("Error getting document:", error); 19 }); 20 }, []) 21 22 const handleChange = (e) => { 23 rulFlg[e.target.value] = [!rulFlg[e.target.value][0], rulFlg[e.target.value][1]] 24 setRulFlg(Object.assign({}, rulFlg)) 25 } 26 27 const handleSubmit = () => { 28 29 } 30 31 32 return ( 33 <div className="selectBan"> 34 <div className="formTitle">禁止事項の選択</div> 35 <div className="formCheckbox"> 36 { 37 Object.keys(rulFlg).map(key => { 38 return ( 39 <label className="banLabel" htmlFor={key} key={key}> 40 <input 41 id={key} 42 type="checkbox" 43 name="bnRules" 44 checked={rulFlg[key][0]} 45 onChange={handleChange} 46 value={key} 47 /> 48 {rulFlg[key][1]} 49 </label> 50 ) 51 }) 52 } 53 </div> 54 <button onClick={handleSubmit}>完了</button> 55 </div> 56 ); 57} 58 59export default SelectBan; 60

投稿2020/10/21 04:50

nakamu

総合スコア82

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

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

0

~~
rulFlg[e.target.value] = !rulFlg[e.target.value]
~~
で代入しちゃっているのが原因かと思われます。

~~const useStateの時で試したことはないのでちょっとあやふやですが、
通常、stateに値を直接代入すると、rerenderは走りませんが、値は書き換わるので、その後で同じ値をsetStateしても、値に変更がないとみなされてrerenderがスキップしていると思います。
~~

投稿2020/10/21 01:43

編集2020/10/21 02:18
Hogeike

総合スコア293

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

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

Hogeike

2020/10/21 02:06 編集

よく考えたら参照は変わっていますからrerenderはされるはずですね。失礼しました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問