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

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

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

Q&A

解決済

1回答

196閲覧

useReducer useContext で管理したステートを変更しても、再度レンダリングされない

sasa0330

総合スコア64

0グッド

0クリップ

投稿2024/01/02 08:02

実現したいこと

  • Reducerのdispach関数を叩いた時に、値を変更する
  • 現状画面更新した時のみ値が反映されるが、リアルタイムで反映させる

発生している問題・分からないこと

Reducerのstateとdispachを呼び出せるカスタムhookを作り、そのhookを介してstate(カードの情報)の中身をmapで展開している。
しかし、dispachでstateに対して 追加 削除 編集 のようなアクションを実施しても、変更した結果が反映されない。
画面更新すると反映される。

エラーメッセージ

error

1window is not defined 2ローカルストレージに値を保存しており、関連するエラーが出ていますが 今回の不具合とは直接関係ないものと推測しています。

該当のソースコード

TypeScript

1// カードの情報のstateと 情報変更用のdispatch を返す hooks 2export const useCards = () => { 3 const strageCards = getLocalStrage("cards"); 4 const defaultCards: Card[] = strageCards ? strageCards : []; 5 const [cards, cardsDispatch] = useReducer(cardsReducer, defaultCards); 6 7 return { cards, cardsDispatch }; 8};

TypeScript

1// カード情報をmapで展開している 2export default function Home() { 3 const { cards } = useCards(); 4 5 return ( 6 <div className="flex w-full flex-wrap gap-2"> 7 {cards && 8 cards.map((card) => ( 9 <React.Fragment key={card.id}> 10 <Card id={card.id}>{card.text}</Card> 11 </React.Fragment> 12 ))} 13 </div> 14 ); 15}

TypeScript

1// カードコンポーネント 2// コンポーネントからカードの削除ができるが、ここで削除してもリアルタイムでデータが反映されない 3function Card({ id, children }: { id: number; children: string }) { 4 const [isEdit, setIsEdit] = useState<boolean>(false); 5 const { cardsDispatch } = useCards(); 6 7 return ( 8 <div className="h-[200px] w-[200px] bg-yellow-200 p-2"> 9 <div>{id}</div> 10 <div className="h-[139px] w-[168px] text-xs text-black"> 11 {isEdit ? ( 12 <textarea 13 autoFocus={true} 14 onBlur={(e) => { 15 setIsEdit(false); 16 cardsDispatch({ 17 type: "UPDATE", 18 payload: { 19 id: id, 20 text: e.target.value, 21 }, 22 }); 23 }} 24 /> 25 ) : ( 26 <div onClick={() => setIsEdit(true)}>{children}</div> 27 )} 28 </div> 29 <button 30 onClick={() => 31 cardsDispatch({ 32 type: "DELETE", 33 payload: { 34 id: Number(id), 35 }, 36 }) 37 } 38 > 39 <Delete /> 40 </button> 41 </div> 42 ); 43} 44 45export default Card;

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果
  • 検索
    • 状態管理フレームワークを使った事例は出てきましたが、useReducer useContext を使った不具合事例が見つかりませんでした。

補足

よろしくお願いいたします。

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2024/01/02 16:06 編集

コメント削除しま〜す😇
guest

回答1

0

ベストアンサー

ぱっと見、Home と Card の両方で useCards() してしまっているのが怪しいです。なので

  • Home でだけ useCards() し、cards と cardsDispatch の両方を受け取っておく。

diff

1- const { cards } = useCards(); 2+ const { cards, cardsDispatch } = useCards();
  • このcardsDispatch を Card に prop 経由で渡す。
  • Card では useCards()しないで、propで渡されてきた cardsDispatch を使う。

といった修正をすれば、問題のすべてが解決するかは分かりませんがなにがしか前進するような気がします。

投稿2024/01/02 15:58

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

sasa0330

2024/01/03 08:07

コメントありがとうございます!ご指摘のとおりでした! > propで渡されてきた cardsDispatch コンポーネントの中でDispatchを呼び出すのではなく、hundleHogeHoge のような関数Propsを用意してDispatchを渡してあげるのが正しそうでした。 ご回答ありがとうございました!
退会済みユーザー

退会済みユーザー

2024/01/03 14:29

> hundleHogeHoge のような関数Propsを用意して あ〜そうですね。そうするのが、子コンポーネントの間口を狭くするという意味でもより丁寧かと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問