前回の『拡張性のあるクイズアプリ簡易版』では、正答(correctAnswer)と、問題文(problemText)を渡せば、別々の問題を表示できることになります。
そこで、これらを、オブジェクトリテラルの配列で定義し、『次の問題』ボタンを押すと、問題が更新されるように拡張します。今後データベースからデータを引っ張ってくる拡張を想定し、作成するオブジェクトリテラル内に、correctAnswer,problemTextプロパティに加え、idプロパティを追加します。
プログラムの前半だけを下記のように変えればよいです。
import { StatusBar } from "expo-status-bar";
import { StyleSheet, Text, View, Button } from "react-native";
import { useState } from "react";
const problemArrayData = [
{
id: 1,
correctAnswer: "b",
problemText:
},
{
id: 2,
correctAnswer: "c",
problemText:
},
{
id: 3,
correctAnswer: "a",
problemText:
},
];
export default function App() {
const correctAnswer = problemArrayData[1].correctAnswer;
const problemText = problemArrayData[1].problemText;
・
・
・
}
一番上に、『次の問題』ボタンを作成します。
export default function App() {
const [correctAnswer, setCorrectAnswer] = useState("");
const [problemText, setProblemText] = useState("");
const pressNextHandler = () => {
const randomNumber = Math.floor(Math.random() * 3);
setCorrectAnswer(problemArrayData[randomNumber].correctAnswer);
setProblemText(problemArrayData[randomNumber].problemText);
};
・ ・
・(省略)
・
return (
<View style={styles.container}>
<Button title="次の問題" onPress={pressNextHandler} />
<Text>{problemText}</Text>
<View style={styles.buttonContainer}>
<Button title={buttonText_a} onPress={pressHandler_a} />
<Button title={buttonText_b} onPress={pressHandler_b} />
<Button title={buttonText_c} onPress={pressHandler_c} />
<Button title={buttonText_d} onPress={pressHandler_d} />
</View>
<Text>{correctText}</Text>
<Text>{explanationText}</Text>
<StatusBar style="auto" />
</View>
);
}
さて、次に、『終了』ボタンを押すと、それまでに、問題に答えた回数(totalAnswerNumber)と、正答数(correctAnswerNumber)を表示できるようにします。
import { StatusBar } from "expo-status-bar";
import { StyleSheet, Text, View, Button } from "react-native";
import { useState } from "react";
const problemArrayData = [
{
id: 1,
correctAnswer: "b",
problemText:
},
{
id: 2,
correctAnswer: "c",
problemText:
},
{
id: 3,
correctAnswer: "a",
problemText:
},
];
export default function App() {
const [correctAnswer, setCorrectAnswer] = useState("");
const [problemText, setProblemText] = useState("");
const [totalAnswerNumber, setTotalAnswerNumber] = useState(0);
const [correctAnswerNumber, setCorrectAnswerNumber] = useState(0);
const [finishedText, setFinishedText] = useState("");
const pressNextHandler = () => {
const randomNumber = Math.floor(Math.random() * 3);
setCorrectAnswer(problemArrayData[randomNumber].correctAnswer);
setProblemText(problemArrayData[randomNumber].problemText);
setTotalAnswerNumber((prevState) => prevState + 1);
};
const pressFinishHandler = () => {
setFinishedText(
`Finished!\r\n解いた問題数は${totalAnswerNumber}\r\n正答数は${correctAnswerNumber}です。`
);
};
const [buttonText_a, setButtonText_a] = useState("a");
const [buttonText_b, setButtonText_b] = useState("b");
const [buttonText_c, setButtonText_c] = useState("c");
const [buttonText_d, setButtonText_d] = useState("d");
const [correctText, setCorrectText] = useState("");
const [explanationText, setExplanationText] = useState("");
const pressHandler_a = () => {
if (buttonText_a == correctAnswer) {
setCorrectText("Correct");
setExplanationText("");
setCorrectAnswerNumber((prevState) => prevState + 1);
} else {
setCorrectText("Incorrect!");
setExplanationText(`正解は${correctAnswer}でした。`);
}
};
const pressHandler_b = () => {
if (buttonText_b == correctAnswer) {
setCorrectText("Correct");
setExplanationText("");
setCorrectAnswerNumber((prevState) => prevState + 1);
} else {
setCorrectText("Incorrect!");
setExplanationText(`正解は${correctAnswer}でした。`);
}
};
const pressHandler_c = () => {
if (buttonText_c == correctAnswer) {
setCorrectText("Correct");
setExplanationText("");
setCorrectAnswerNumber((prevState) => prevState + 1);
} else {
setCorrectText("Incorrect!");
setExplanationText(`正解は${correctAnswer}でした。`);
}
};
const pressHandler_d = () => {
if (buttonText_d == correctAnswer) {
setCorrectText("Correct");
setExplanationText("");
setCorrectAnswerNumber((prevState) => prevState + 1);
} else {
setCorrectText("Incorrect!");
setExplanationText(`正解は${correctAnswer}でした。`);
}
};
return (
<View style={styles.container}>
<View style={styles.nextFinishButtonContainer}>
<Button title="次の問題" onPress={pressNextHandler} />
<Button title="終了" onPress={pressFinishHandler} />
</View>
<Text>{problemText}</Text>
<View style={styles.selectButtonContainer}>
<Button title={buttonText_a} onPress={pressHandler_a} />
<Button title={buttonText_b} onPress={pressHandler_b} />
<Button title={buttonText_c} onPress={pressHandler_c} />
<Button title={buttonText_d} onPress={pressHandler_d} />
</View>
<Text>{correctText}</Text>
<Text>{explanationText}</Text>
<Text style={styles.finishedText}>{finishedText}</Text>
<StatusBar style="auto" />
</View>
);
}
const styles = StyleSheet.create({
container: {
backgroundColor: "#fff",
alignItems: "center",
justifyContent: "center",
},
nextFinishButtonContainer: {
flexDirection: "row",
justifyContent: "space-around",
width: "80%",
},
selectButtonContainer: {
flexDirection: "row",
justifyContent: "space-around",
width: "80%",
},
finishedText: {
marginTop: 30,
fontSize: 20,
},
});
データを別のJavaScript に記述し、App.jsへはimport してきます。
データを入れる際に、CodeWhisperがひな形を自動で作成してくれるのでかなり楽です。
ProblemEntity.js
App.jsの冒頭
import { StatusBar } from "expo-status-bar";
import { StyleSheet, Text, View, Button } from "react-native";
import { useState } from "react";
import { problemArrayData } from "./ProblemEntity";