在 React Native 中使用嵌套的三元运算符会带来数组比较的意外结果
Using nested tenary operator brings unintended result from array comparison in React Native
我一直致力于在 React Native 项目中制作测验组件。我的目标是构建如下所示的屏幕截图。
https://i.stack.imgur.com/khrDO.png
There's one problem I'm facing is that when a correct answer is selected, other options that were already selected become activated as same as the answer.
我希望在选择正确答案后,选择的错误答案像上面的屏幕截图一样保留删除线。
这是与该问题相关的代码。
const Quiz: React.FC<QuizProps> = ({
options,
correctAnswerIndex
}) => {
const [accSelectedOptionIdx, setAccSelectedOptionIdx] = useState<number[]>([]);
const isCorrectAnswer = (
selectedOption: number[],
correctAnswer: number[] | undefined
) => {
const matchCorrectIdxNumber = selectedOption.filter((ele) =>
correctAnswer?.includes(ele)
);
return matchCorrectIdxNumber.length === correctAnswer?.length;
};
const onPress = (idx: number) => {
if (!user) {
history.push('/login', {
from: pathname,
});
} else {
setAccSelectedOptionIdx((prev) => [...prev, idx]);
}
};
const isOptAlreadySelected = (idx: number) => {
const result = accSelectedOptionIndex.includes(idx);
return result;
};
return (
<View>
{options?.map((option, idx) => {
return (
<>
<TouchableOpacity
onPress={onPress(idx));
disabled={isCorrectAnswer(accSelectedOptionIndex, correctAnswerIndex)}
key={option}
style={{
flex: 1,
flexDirection: 'row',
justifyContent: 'space-between',
}}
>
<Text
selectable
style={
isOptAlreadySelected(idx)
? // if an option being mapped over was already selected
isCorrectAnswer(accSelectedOptionIndex, correctAnswerIndex)
? // if the option that was already selected is correct answer, then apply correct type style to it
[styles.defaultOptionTxt, styles.correctAnswerTxt]
: // if it's incorrect answer, apply incorrect type style
[styles.defaultOptionTxt, styles.wrongAnswerTxt]
: // if an option is not selected yet, apply default style
styles.defaultOptionTxt
}
>
{option}
</Text>
(...omitted)
))}
代码段中的一种数据'correctIndexes'是服务器提供的数字数组。
例如)correctIndexes = [1]
我遇到问题的方法是比较包含用户选择累积的索引的数组和 correctAnswerIndex,这样我就可以检查数组中是否有 correctAnswerIndex 编号。
然而,我描述的错误发生在选择正确答案时,因为数组 'accSelectedOptionIndex' 同时具有 correctAnswerIndex,这导致更改删除线选项。
如有任何建议,我们将不胜感激。
谢谢。
要解决此问题,点击答案选项不应影响之前选择的错误选项,这是由 isCorrectAnswer(accSelectedOptionIndex, correctAnswerIndex) ? [styles.defaultOptionTxt, styles.correctAnswerTxt] : [styles.defaultOptionTxt, styles.wrongAnswerTxt]
引起的。
因此,可以通过比较整个选项中的两个数组和索引来定义所有三种情况的状态,例如正确、错误、默认或尚未,这样每次用户单击一个选项时,它就会有我们定义的自己的状态,同时不影响任何其他选项。
{options?.map((option, idx) => {
const status = _.includes(accSelectedOptionIdx, idx)
? _.includes(correctIndexes, idx)
? 'correct'
: 'wrong'
: 'yet';
return (
<>
<TouchableOpacity
onPress={onPress(idx));
disabled={isCorrectAnswer(accSelectedOptionIndex, correctAnswerIndex)}
key={option}
style={{
flex: 1,
flexDirection: 'row',
justifyContent: 'space-between',
}}
>
<Text
selectable
style={
styles.defaultOptionTxt,
status === 'correct'
? styles.correctAnswerTxt
: status === 'wrong'
? styles.wrongAnswerTxt
: {},
]}
>
{option}
</Text>
(...omitted)
))}
我一直致力于在 React Native 项目中制作测验组件。我的目标是构建如下所示的屏幕截图。
https://i.stack.imgur.com/khrDO.png
There's one problem I'm facing is that when a correct answer is selected, other options that were already selected become activated as same as the answer.
我希望在选择正确答案后,选择的错误答案像上面的屏幕截图一样保留删除线。
这是与该问题相关的代码。
const Quiz: React.FC<QuizProps> = ({
options,
correctAnswerIndex
}) => {
const [accSelectedOptionIdx, setAccSelectedOptionIdx] = useState<number[]>([]);
const isCorrectAnswer = (
selectedOption: number[],
correctAnswer: number[] | undefined
) => {
const matchCorrectIdxNumber = selectedOption.filter((ele) =>
correctAnswer?.includes(ele)
);
return matchCorrectIdxNumber.length === correctAnswer?.length;
};
const onPress = (idx: number) => {
if (!user) {
history.push('/login', {
from: pathname,
});
} else {
setAccSelectedOptionIdx((prev) => [...prev, idx]);
}
};
const isOptAlreadySelected = (idx: number) => {
const result = accSelectedOptionIndex.includes(idx);
return result;
};
return (
<View>
{options?.map((option, idx) => {
return (
<>
<TouchableOpacity
onPress={onPress(idx));
disabled={isCorrectAnswer(accSelectedOptionIndex, correctAnswerIndex)}
key={option}
style={{
flex: 1,
flexDirection: 'row',
justifyContent: 'space-between',
}}
>
<Text
selectable
style={
isOptAlreadySelected(idx)
? // if an option being mapped over was already selected
isCorrectAnswer(accSelectedOptionIndex, correctAnswerIndex)
? // if the option that was already selected is correct answer, then apply correct type style to it
[styles.defaultOptionTxt, styles.correctAnswerTxt]
: // if it's incorrect answer, apply incorrect type style
[styles.defaultOptionTxt, styles.wrongAnswerTxt]
: // if an option is not selected yet, apply default style
styles.defaultOptionTxt
}
>
{option}
</Text>
(...omitted)
))}
代码段中的一种数据'correctIndexes'是服务器提供的数字数组。
例如)correctIndexes = [1]
我遇到问题的方法是比较包含用户选择累积的索引的数组和 correctAnswerIndex,这样我就可以检查数组中是否有 correctAnswerIndex 编号。
然而,我描述的错误发生在选择正确答案时,因为数组 'accSelectedOptionIndex' 同时具有 correctAnswerIndex,这导致更改删除线选项。
如有任何建议,我们将不胜感激。
谢谢。
要解决此问题,点击答案选项不应影响之前选择的错误选项,这是由 isCorrectAnswer(accSelectedOptionIndex, correctAnswerIndex) ? [styles.defaultOptionTxt, styles.correctAnswerTxt] : [styles.defaultOptionTxt, styles.wrongAnswerTxt]
引起的。
因此,可以通过比较整个选项中的两个数组和索引来定义所有三种情况的状态,例如正确、错误、默认或尚未,这样每次用户单击一个选项时,它就会有我们定义的自己的状态,同时不影响任何其他选项。
{options?.map((option, idx) => {
const status = _.includes(accSelectedOptionIdx, idx)
? _.includes(correctIndexes, idx)
? 'correct'
: 'wrong'
: 'yet';
return (
<>
<TouchableOpacity
onPress={onPress(idx));
disabled={isCorrectAnswer(accSelectedOptionIndex, correctAnswerIndex)}
key={option}
style={{
flex: 1,
flexDirection: 'row',
justifyContent: 'space-between',
}}
>
<Text
selectable
style={
styles.defaultOptionTxt,
status === 'correct'
? styles.correctAnswerTxt
: status === 'wrong'
? styles.wrongAnswerTxt
: {},
]}
>
{option}
</Text>
(...omitted)
))}