React強化月間 6日目

おはようございます。
朝一でTailwindCSSの並び替えを入れました。

./tailwind.config.tsが自分は./tailwind.config.jsだったので直したら動いた。
こういうのにすぐ気づけるようになったのいいね。

今日の目標

引き続きクイズアプリの機能見直し。
1時間考えてもわからないので最初からやります。

こんなんで仕事出来るようになるんかな。。

import React, { useState, useEffect } from "react";
import { QuestionList } from "./QuestionList";

const questions = QuestionList();
const answerList = questions.map((question) => question.answers[0]);
console.log(`${answerList[0]}`);

const Question = () => {
  const [restQuestions, setRestQuestions] = useState(questions);
  const [selectQuestions, setSelectQuestions] = useState(
    restQuestions[0].question
  );
  const [selectAnswer, setSelectAnswer] = useState(restQuestions[0].answers);
  const [flag, setFlag] = useState(false);

  useEffect(() => {}, []);
  return (
    <>
      <div className="flex h-96 flex-col items-center justify-center pt-10">
        <div className="h-80 w-5/6">{selectQuestions}</div>

        {selectAnswer.map((answer, i) => (
          <button
            key={i}
            className="mb-2 w-60 border-4 border-current text-center"
            onClick={() => {
              setFlag(!flag);
            }}
          >
            {answer}
          </button>
        ))}
      </div>
    </>
  );
};
export default Question;

問題の並び替えを考えなかったら上記コードで出来る。

次に必要なことは
・元の問題の1問目が正解という定義づけ
・問題の並べ替え

理解できてなかったこと①

const questions =[
    {
      question:
        "顧客が商品やサービスを認知して購入を決定するまでのプロセスを指すものを何というか。",
      answers: [
        "カスタマージャーニー",
        "ペルソナ",
        "ターゲティング",
        "セグメンテーション",
      ],
    }]

多分今までquestions をオブジェクト{}と勘違いしてたっぽい。
あと console.log(questions [0].answers[0]) → "カスタマージャーニー"

ここらへんの指定が頭で整理出来てなかったっぽい。

理解できてなかったこと②

 splice の使い方が分かってなくて

const onClickNextQuestion = () => {
    setRestQuestions(restQuestions.splice(random, 1));
    setAnswerList(answerList.splice(random, 1));
    setRandom(Math.floor(Math.random() * restQuestions.length));
    setSelectQuestions(restQuestions[random].question);
  };

これをすると、setRestQuestions の時にspliceして新しい配列を代入後、setSelectQuestions(restQuestions[random].question); ここで もう一度spliceされてるっぽい。なので

const onClickNextQuestion = () => {
    const newRestQuestions = restQuestions.splice(random, 1)
    setRestQuestions(newRestQuestions);
    const newSetAnswerList =answerList.splice(random, 1)
    setAnswerList(newSetAnswerList);
    setRandom(Math.floor(Math.random() * restQuestions.length));
    setSelectQuestions(newRestQuestions[random].question);
  };

一度新しい変数に入れる必要がある。

理解できてなかったこと③

const months = ['Jan', 'March', 'April', 'June'];
const a = months
a.splice(0,1)

console.log(months)
//["March","April","June"]

これをすると、monthsが["March","April","June"]になる。
だけど、

const months = ['Jan', 'March', 'April', 'June'];
const a = [...months]
const b = a.splice(0,1)

console.log(months)
//["Jan","March","April","June"]
console.log(a)
//["March","April","June"]
console.log(b)
//["Jan"]

これをすると、monthsが["Jan","March","April","June"]のまま。

理由は a = months は aの場所をmonthsでしている
[…months]はスプレッド構文してaに新しい配列を作ってる。

この辺は何度か勉強して見てるはずなのにぼやっとスルーしちゃってた。

理解できてなかったこと④

const newSetAnswerList = [...answerList];    
const spliceNewSetAnswerList = newSetAnswerList.splice(random, 1)[0];

②と③を合わせると、こうなるんだけど、spliceNewSetAnswerList を定義した際に本体の newSetAnswerList は1個減っている。

const questions = QuestionList();
const Question = () => {
  const [restQuestions, setRestQuestions] = useState(questions);
  const [answerList, setAnswerList] = useState(
    questions.map((question) => question.answers[0])
  );
  const [random, setRandom] = useState(
    Math.floor(Math.random() * questions.length)
  );
  const [selectQuestions, setSelectQuestions] = useState(
    restQuestions[random].question
  );
  const [selectAnswer, setSelectAnswer] = useState(
    answerList[random]
  );

  const [flag, setFlag] = useState(false);

  const onClickNextQuestion = () => {
    const newRestQuestions = [...restQuestions];
    const spliceNewRestQuestions = newRestQuestions.splice(random, 1)[0];
    setRestQuestions(newRestQuestions);
    const newSetAnswerList = [...answerList];    
    const spliceNewSetAnswerList = newSetAnswerList.splice(random, 1)[0];
    setAnswerList(newSetAnswerList);
    setRandom(Math.floor(Math.random() * newRestQuestions.length));
    setSelectQuestions(spliceNewRestQuestions.question);
    setSelectAnswer(spliceNewSetAnswerList);
  };

最終的にこうなると。・・・難しすぎん?
ReactというよりJSの話だけど、理解に4時間かかった。

そしてなんやかんや

import React, { useState, useEffect } from "react";
import { QuestionList } from "./QuestionList";

const questions = QuestionList();

const shuffleArray = (array) => {
  for (let i = array.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * i);
    [array[i], array[j]] = [array[j], array[i]];
  }
  return array;
};

const Question = () => {
  const [restQuestions, setRestQuestions] = useState(questions);
  const [answerList, setAnswerList] = useState(
    questions.map((question) => question.answers[0])
  );

  const [random, setRandom] = useState(0);
  const [selectQuestions, setSelectQuestions] = useState("");
  const [selectAnswer, setSelectAnswer] = useState("");
  const [answerButton, setAnswerButton] = useState([]);

  const onClickNextQuestion = () => {
    const newRestQuestions = [...restQuestions];
    const spliceNewRestQuestions = newRestQuestions.splice(random, 1)[0];
    const newSetAnswerList = [...answerList];
    const spliceNewSetAnswerList = newSetAnswerList.splice(random, 1)[0];

    if (restQuestions.length > 0) {
      setAnswerButton(shuffleArray(restQuestions[random].answers));
      setRestQuestions(newRestQuestions);
      setAnswerList(newSetAnswerList);
      setRandom(Math.floor(Math.random() * newRestQuestions.length));
      setSelectQuestions(spliceNewRestQuestions.question);
      setSelectAnswer(spliceNewSetAnswerList);
    }
  };

  const onClickAnswerButton = (index) => {
    if (selectAnswer == answerButton[index]) {
      console.log(`正解`);
    } else {
      console.log(`不正解`);
    }
  };

  useEffect(() => {}, []);

  return (
    <>
      <div className="flex h-96 flex-col items-center justify-center pt-10">
        <div className="h-80 w-5/6">{selectQuestions}</div>
        <div className="h-80 w-5/6">{selectAnswer}</div>

        {answerButton.map((answer, index) => (
          <button
            key={index}
            onClick={() => {
              onClickAnswerButton(index);
            }}
            className="mb-2 w-60 border-4 border-current text-center"
          >
            {answer}
          </button>
        ))}
        <button
          onClick={() => {
            onClickNextQuestion();
          }}
          className="mb-2 w-60 border-4 border-current text-center"
        >
          次の問題
        </button>
      </div>
    </>
  );
};
export default Question;


出来た!

機能

・問題の順番はランダム
・正解はselectAnswerに保存してあり選んだボタンで条件判定
・次の問題を押すと問題数を減らしてセット
・問題がなくなると取り合えずエラーは出ずに止まる仕様

疲れた・・・

JSで出来たのになんでこんな難しかったんだろ。
JSの時は理解してなかったのかもしれない。

書き出すこと大事やね。

今もspliteとmapとスプレッド構文の挙動が怪しいけど。。
あとはウイニングランですわ。

いい感じ。

せっかくだから世に出せる何かを作りたい。

明日もうちょっと手直しして終わりかなぁ。

この記事が気に入ったらサポートをしてみませんか?