I am building a small quiz in react native. On my screen, I want the user to chose several correct answers from a choice of 4-6 options. I build a custom checkbox for that. If the correct answers are checked (and all wrong answers are unchecked) the user should get a message that the answer was correct.
Here is the custom checkbox component. I only included the code for three boxes to make the code a bit shorter:
import { TouchableOpacity, StyleSheet, View, Text } from "react-native";
import { FontAwesome } from "@expo/vector-icons";
function AnswerContainer_CheckBox(props) {
const [userInput, setUserInput] = useState("");
const answerHandler = () => {
if (userInput == props.finalAnswer) {
dispatch(answerTrue());
}
};
const [checked_1, setChecked_1] = useState(false);
const [checked_2, setChecked_2] = useState(false);
const [checked_3, setChecked_3] = useState(false);
/*Visibility
if set to false via props, the checkbox won't show
*/
const [box_1_Visibility, setBox_1_Visibility] = useState(
props.box_1_Visibility
);
const [box_2_Visibility, setBox_2_Visibility] = useState(
props.box_2_Visibility
);
const [box_3_Visibility, setBox_3_Visibility] = useState(
props.box_3_Visibility
);
/* Functions to chech and uncheck ityems*/
const checkedHandler_1 = () => {
if (checked_1 == false) {
setChecked_1(true);
setUserInput(userInput + props.box_1_Letter);
answerHandler();
} else {
setChecked_1(false);
setUserInput(userInput.replace(props.box_1_Letter,""));
answerHandler();
}
};
const checkedHandler_2 = () => {
if (checked_2 == false) {
setChecked_2(true);
setUserInput(userInput + props.box_2_Letter);
answerHandler();
} else {
setChecked_2(false);
setUserInput(userInput.replace(props.box_2_Letter,""));
answerHandler();
}
};
const checkedHandler_3 = () => {
if (checked_3 == false) {
setChecked_3(true);
setUserInput(userInput + props.box_3_Letter);
answerHandler();
} else {
setChecked_3(false);
setUserInput(userInput.replace(props.box_4_Letter,""));
answerHandler();
}
};
return (
<View>
{/* Checkbox 1 */}
<TouchableOpacity
onPress={() => {
checkedHandler_1();
}}
>
<View
style={
(box_1_Visibility === true && styles.mainContainer) || styles.hide
}
>
<View style={styles.icon}>
<FontAwesome
name={checked_1 == true ? "check-square" : "square-o"}
size={24}
color={checked_1 == true ? "#3787FF" : "#BFD3E5"}
/>
</View>
<Text style={styles.checkButtonText}>{props.box_1_Label}</Text>
</View>
</TouchableOpacity>
{/* Checkbox 2 */}
<TouchableOpacity
onPress={() => {
checkedHandler_2();
}}
>
<View
style={
(box_2_Visibility === true && styles.mainContainer) || styles.hide
}
>
<View style={styles.icon}>
<FontAwesome
name={checked_2 == true ? "check-square" : "square-o"}
size={24}
color={checked_2 == true ? "#3787FF" : "#BFD3E5"}
/>
</View>
<Text style={styles.checkButtonText}>{props.box_2_Label}</Text>
</View>
</TouchableOpacity>
{/* Checkbox 3 */}
<TouchableOpacity
onPress={() => {
checkedHandler_3();
}}
>
<View
style={
(box_3_Visibility === true && styles.mainContainer) || styles.hide
}
>
<View style={styles.icon}>
<FontAwesome
name={checked_3 == true ? "check-square" : "square-o"}
size={24}
color={checked_3 == true ? "#3787FF" : "#BFD3E5"}
/>
</View>
<Text style={styles.checkButtonText}>{props.box_3_Label}</Text>
</View>
</TouchableOpacity>
</View>
);
}
So what is happening here: onPress the checkedHandler-function checks the state. If "false" it will change it to "true". If it is "true" it will change to "false". Depending on the state, the style of the checkbox will change. The checkedHandler-function will also update the string within "userInput" depending on the state. The content of the string is catched via props from the parent component ("box_1_Letter" etc).
This is how I added the component in my screen/parent component:
<AnswerContainer_CheckBox
finalAnswer={"AC"}
box_1_Visibility={true}
box_2_Visibility={true}
box_3_Visibility={true}
box_4_Visibility={true}
box_5_Visibility={false}
box_6_Visibility={false}
box_1_Label={"Shanghai"}
box_1_Letter={"A"}
box_2_Label={"Paris"}
box_2_Letter={"B"}
box_3_Label={"New York"}
box_3_Letter={"C"}
box_4_Label={"Berlin"}
box_4_Letter={"D"}
/>
As you can see I first define how many boxes should be visible and I also add a label to each box and the associated "letter". "finalAnswer" contains the correct answer.
Now comes my problem: let's say in my example "Shanghai" and "New York" are the correct answers. Both boxes have to be checked while all other boxes have to be unchecked. How do I check that within the parent component/Screen?. My solution does not work. The user would have to check the boxes in the right order (and even then it somehow didn't work). The solution would also only be available within the component, not the parent. I do not want to create a global state with redux for this.
Any help appreciated (be aware: I am pretty new to this :-)