📝
「RemixV2」で簡単な漢字読みクイズアプリを作成する
クイズアプリを作ります。
要件・仕様
- 4択クイズ
- 漢字のクイズ
- 5問
- 正解率出す
1. 問題と答えを作る
app/data.ts
のファイルを新規作成してデータを用意する。
app/data.ts
// ./app/data.ts
export const quizQuestions = {
reading_questions: [
{
question: "「義理」の正しい読み方はどれか?",
options: ["ぎり", "よし", "ぎれい", "りぎ"],
answer: "ぎり"
},
{
question: "「憂鬱」の読み方はどれか?",
options: ["ゆうゆつ", "ゆううつ", "おもいみ", "うれい"],
answer: "ゆううつ"
},
{
question: "「躊躇」の読み方はどれか?",
options: ["ちゅうちょ", "ちゅうど", "ためらい", "ちょうちょ"],
answer: "ちゅうちょ"
},
{
question: "「瑞々しい」の読み方はどれか?",
options: ["みずみずしい", "すいすいしい", "りんりんしい", "ずいずいしい"],
answer: "みずみずしい"
},
{
question: "「喧嘩」の読み方はどれか?",
options: ["けんか", "げんか", "こんか", "けんが"],
answer: "けんか"
}
]
};
2. スタイルを書く
app/styles.ts
のファイルを新規作成してCSSを用意する。
app/styles.ts
/* src/App.css */
.quizPage {
font-family: Arial, sans-serif;
margin: 20px;
}
.questionSection {
margin-bottom: 20px;
}
.questionCount {
margin-bottom: 10px;
}
.questionText {
margin-bottom: 20px;
}
.answerSection button {
display: block;
width: 100%;
padding: 10px;
margin-bottom: 10px;
border: 1px solid #ddd;
background-color: #f8f8f8;
cursor: pointer;
}
3. スタイルを適用する
app/root.ts
import {
Links,
Meta,
Outlet,
Scripts,
ScrollRestoration,
} from "@remix-run/react";
+import type { LinksFunction } from "@remix-run/node"; // or + cloudflare/deno
+import styles from "~/styles.css?url";
+export const links: LinksFunction = () => [
+ { rel: "stylesheet", href: styles },
+];
4. _indexページを更新する
app\routes\_index.tsx
のファイルを更新する
app/data.ts
import React, { useState } from 'react';
import { json, LoaderFunction } from "@remix-run/node";
import { useLoaderData } from "@remix-run/react";
import { quizQuestions } from '~/data';
interface Question {
question: string;
options: string[];
answer: string;
}
export const loader: LoaderFunction = async () => {
return json(quizQuestions);
};
const QuizPage: React.FC = () => {
const loadedData = useLoaderData<typeof quizQuestions>();
const [currentQuestionIndex, setCurrentQuestionIndex] = useState(0);
const [selectedAnswers, setSelectedAnswers] = useState<string[]>([]);
const [showResult, setShowResult] = useState(false);
const questions: Question[] = loadedData.reading_questions;
const handleAnswerSelection = (selectedOption: string) => {
const newAnswers = [...selectedAnswers, selectedOption];
setSelectedAnswers(newAnswers);
if (currentQuestionIndex + 1 < questions.length) {
setCurrentQuestionIndex(currentQuestionIndex + 1);
} else {
setShowResult(true); // クイズ終了
}
};
const resetQuiz = () => {
setCurrentQuestionIndex(0);
setSelectedAnswers([]);
setShowResult(false);
};
const calculateScore = () => {
let score = 0;
questions.forEach((question, index) => {
if (question.answer === selectedAnswers[index]) {
score += 1;
}
});
return score;
};
if (showResult) {
const score = calculateScore();
return (
<div className="resultSection">
<h2>クイズ結果</h2>
<p>あなたのスコアは {score} / {questions.length} です。</p>
<button onClick={resetQuiz}>もう一度チャレンジ</button>
</div>
);
}
return (
<div className="quizPage">
<div className="questionSection">
<div className="questionCount">
<span>Question {currentQuestionIndex + 1}</span>/{questions.length}
</div>
<div className="questionText">{questions[currentQuestionIndex].question}</div>
</div>
<div className="answerSection">
{questions[currentQuestionIndex].options.map((option, index) => (
<button key={index} onClick={() => handleAnswerSelection(option)}>
{option}
</button>
))}
</div>
</div>
);
};
export default QuizPage;
完成😆
Discussion