React Native问答应用:解决题目重复与题库耗尽重置问题
解决React Native问答应用的题目重复与题库重置问题
问题根源
- 直接修改导入的原始
data数组(引用类型),导致原始数据被永久破坏;同时newData和data指向同一块内存,concat操作无法重置题库(concat返回新数组,不会修改原数组)。 - 用
sort(() => 0.5 - Math.random())做随机排序是原地修改数组,且递归筛选分类的逻辑容易出现重复选题的情况。
解决方案代码
先调整数据导入和状态定义,用React状态维护当前可用的题目池,完全隔离原始数据:
import { data as originalData } from './data.js'; import { useState } from 'react'; // 组件内部状态 const [availableQuestions, setAvailableQuestions] = useState([...originalData]); const [questions, setQuestions] = useState([]); const [selectedOptions, setSelectedOptions] = useState({}); const [showResult, setShowResult] = useState(false);
重写getQuestions函数,优化随机选题逻辑并处理题库重置:
const getQuestions = () => { // 处理题库耗尽的情况,直接重置为原始数据副本 let currentAvailable = availableQuestions; if (currentAvailable.length === 0) { currentAvailable = [...originalData]; setAvailableQuestions(currentAvailable); } setSelectedOptions({}); setShowResult(false); // 筛选当前分类的题目 let categoryQuestions = currentAvailable.filter(q => q.category === category); // 如果当前分类无可用题目,重置整个题库后再筛选 if (categoryQuestions.length === 0) { currentAvailable = [...originalData]; categoryQuestions = currentAvailable.filter(q => q.category === category); setAvailableQuestions(currentAvailable); } // 随机取一个题目(比sort更高效且稳定) const randomIdx = Math.floor(Math.random() * categoryQuestions.length); setQuestions([categoryQuestions[randomIdx]]); };
修改handleNext函数,从可用题目池中移除已答题目:
const handleNext = () => { questions.forEach(question => { if (selectedOptions[question.id] === question.correctOption) { // 建议给每个题目加唯一id,便于匹配 // 从可用池移除当前题目 setAvailableQuestions(prev => prev.filter(q => q.id !== question.id)); navigation.navigate('Correct Site'); getQuestions(); } // 这里可以补充回答错误时的逻辑 }); };
关键改进点
- 用
availableQuestions状态维护动态题库,完全不修改原始导入数据,彻底解决引用导致的重置问题 - 重置题库时创建原始数据的新副本
[...originalData],确保每次重置都是全新的题目集合 - 用随机索引选题目,替代原地排序的方式,逻辑更清晰且性能更好
- 增加了当前分类题目耗尽时的兜底处理,保证用户能继续答题
内容的提问来源于stack exchange,提问作者babinicz
相关产品推荐
相关产品推荐

