usestateで非同期でsetされる変数を読み取れない場合の対処方法を知りたい。

前提

react×TSでクイズアプリを作っています。
ランダムでクイズを選択肢、それをクイズリストに追加していきたいのですが、上手く追加できずに困っています。

実現したいこと

  • setQuizeez();後のsetQuestion()の際に、quizListの値が参照できるようにしたい。

発生している問題・エラーメッセージ

setQuizeez()によって、quizListにクイズが追加されたのち、setQuestion()が実行できるとよいのですが、setQuizList()が非同期で走ってしまうため、上手くQuizListの値が参照できません。
このような場合、どのような対処方法が良いのでしょうか。

該当のソースコード

ts

import React, { ChangeEvent, useEffect, useState } from "react";import { quizzes, Quiz } from "../data/quizzes"; export type GameSceneProps = { setScene: (scene: string) => void;}; export const GameScene: React.FC<GameSceneProps> = ({ setScene }) => { const [quizProgress, setQuizProgress] = useState<number>(1); const [inputAnswer, setInputAnswer] = useState<string>(""); const [inputCheck, setinputCheck] = useState<string>(""); const [question, setQuestion] = useState<string>(""); const [answer, setAnswer] = useState<string>(""); const questinoNum = 3; const [quizList, setQuizList] = useState<Quiz[]>([]); const randomNumber = (max: number) => { return Math.floor(Math.random() * max); }; const setQuizeez = () => { const max = quizzes.length; console.log(quizList); for (let i = 0; i < questinoNum; i++) { console.log(quizzes[randomNumber(max)]); setQuizList([...quizList, quizzes[randomNumber(max)]]); } console.log(quizList); }; const onchangeText = (e: ChangeEvent<HTMLInputElement>) => { setInputAnswer(e.target.value); }; const submitAnswer = () => { console.log(inputAnswer); console.log(answer); if (inputAnswer == answer) { setQuizProgress((count) => count + 1); setinputCheck(""); console.log(quizProgress); console.log(quizList); setQuestion(quizList[quizProgress - 1]["question"]); setAnswer(quizList[quizProgress - 1]["answer"]); } else { setinputCheck("違うよ!"); } setInputAnswer(""); }; useEffect(() => { console.log(quizList); setQuizeez(); setQuestion(quizList[quizProgress - 1]["question"]); setAnswer(quizList[quizProgress - 1]["answer"]); }, []); useEffect(() => { if (quizProgress === 4) { setScene("result"); } }, [quizProgress]);

試したこと

以下のように、quizListが更新された際に、setQuestion()が動作するように変更した。
しかし、そもそもsetQuizeez()の中で、quizListが更新されない状態で、for文が回っているのでquestionNum=3の場合は3回目のquizzes[randomNumber(max)]がsetQuizListに収納された状態になってしまう。(本来はクイズが3問収納されて欲しい)

ts

const setQuizeez = () => { const max = quizzes.length; for (let i = 0; i < questinoNum; i++) { console.log(quizzes[randomNumber(max)]); setQuizList([...quizList, quizzes[randomNumber(max)]]); } }; useEffect(() => { console.log(quizList); setQuizeez(); }, []); useEffect(() => { if (quizList.length !== 0) { setQuestion(quizList[quizProgress - 1]["question"]); setAnswer(quizList[quizProgress - 1]["answer"]); } }, [quizList]);

ここに問題に対して試したことを記載してください。

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

コメントを投稿

0 コメント