如何实现点击按钮在Modal中展示不重复的随机问答
解决方案
要实现已展示的问答不再重复,核心做法是维护一个存储未使用问答的状态数组,每次随机抽取后将该问答从数组中移除,确保后续不会再选中它。具体修改如下:
关键调整点
- 新增
remainingQuestions状态,初始化为原问答数组的副本(避免修改原数组) - 新增
currentQuestion状态,存储当前选中的问答内容,替代原来的index - 重写随机选择逻辑,从剩余数组中选取并更新状态
- 处理所有问答已用完的边界情况
修改后的完整代码
const Arrayorange = [ { question: "question 1", reply: "Reply 1", }, { question: "question 2", reply: "Reply 2", }, { question: "question 3", reply: "Reply 3", } ]; export function Orange() { const [stateModal, changeStateModal] = useState(false); // 维护剩余未使用的问答数组 const [remainingQuestions, setRemainingQuestions] = useState([...Arrayorange]); // 存储当前选中的问答 const [currentQuestion, setCurrentQuestion] = useState(Arrayorange[0]); function openandchange(){ changeOrange(); openModal(); } function changeOrange() { // 所有问答已展示完毕的处理逻辑 if (remainingQuestions.length === 0) { alert("所有问答已展示完毕!"); // 可选:取消注释以下代码重置游戏 // setRemainingQuestions([...Arrayorange]); // setCurrentQuestion(Arrayorange[0]); return; } // 从剩余数组中随机选取索引 const randomIndex = Math.floor(Math.random() * remainingQuestions.length); const selectedQuestion = remainingQuestions[randomIndex]; // 更新当前选中的问答 setCurrentQuestion(selectedQuestion); // 移除已选中的问答,生成新的剩余数组 setRemainingQuestions(prev => prev.filter((_, idx) => idx !== randomIndex)); } function openModal(){ changeStateModal(!stateModal); } const audio = new Audio(cardsound); function openwithsound(){ openandchange(); audio.play(); } return ( <div> <button className="btn" onClick={openwithsound}><IoIosBody/></button> <ModalOrange state={stateModal} changeState={changeStateModal} titulo="Question" > <Content> <h1>{currentQuestion.question}</h1> <p>{currentQuestion.reply}</p> </Content> </ModalOrange> </div> ); }
代码说明
- 状态初始化:用
[...Arrayorange]创建原数组的副本存入remainingQuestions,避免直接修改原始数据;currentQuestion初始化为第一个问答项。 - 随机选择逻辑:先判断剩余数组是否为空,为空则提示用户(也可选择重置数组重新开始);随机生成索引选中问答后,通过
filter方法移除该问答,更新剩余数组。 - 内容渲染:直接通过
currentQuestion访问问答内容,无需再通过索引读取原数组,代码更简洁直观。
内容的提问来源于stack exchange,提问作者Lucas Caballero
相关产品推荐
相关产品推荐

