You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NextJs测验应用:如何跟踪打乱数组中的正确答案索引

解决测验应用选项判断问题的两种方案

方案一:给选项添加正确标识(推荐)

处理选项数组时,不要只存纯文本,改成包含text和isCorrect的对象,这样打乱后每个选项都自带判断依据,无需跟踪索引:

import { useState, useEffect } from 'react';

export default function QuizQuestion({ question }) {
  const { correctAnswer, wrongAnswers } = question;
  const [options, setOptions] = useState([]);

  useEffect(() => {
    // 构造带正确标识的选项数组
    const allOptions = [
      { text: correctAnswer, isCorrect: true },
      ...wrongAnswers.map(ans => ({ text: ans, isCorrect: false }))
    ];
    // 用无偏序的Fisher-Yates算法洗牌
    const shuffled = shuffleArray(allOptions);
    setOptions(shuffled);
  }, [correctAnswer, wrongAnswers]);

  // Fisher-Yates洗牌算法,避免sort方法的概率偏序问题
  function shuffleArray(array) {
    const newArray = [...array];
    for (let i = newArray.length - 1; i > 0; i--) {
      const j = Math.floor(Math.random() * (i + 1));
      [newArray[i], newArray[j]] = [newArray[j], newArray[i]];
    }
    return newArray;
  }

  const handleOptionClick = (option) => {
    if (option.isCorrect) {
      console.log('回答正确!');
      // 这里添加正确后的业务逻辑,比如加分、跳转下一题
    } else {
      console.log('回答错误!');
      // 错误后的逻辑,比如显示正确答案、扣分
    }
  };

  return (
    <div>
      <h3>{question.text}</h3>
      <div className="options">
        {options.map((option, idx) => (
          <button
            key={idx}
            onClick={() => handleOptionClick(option)}
            className="option-btn"
          >
            {option.text}
          </button>
        ))}
      </div>
    </div>
  );
}

方案二:直接对比选项与原始正确答案

如果不想修改数组结构,也可以在点击时直接把选中的选项文本和原始的correctAnswer对比,无需额外跟踪索引:

import { useState, useEffect } from 'react';

export default function QuizQuestion({ question }) {
  const { correctAnswer, wrongAnswers } = question;
  const [options, setOptions] = useState([]);

  useEffect(() => {
    // 合并去重后洗牌
    const allOptions = [...new Set([correctAnswer, ...wrongAnswers])];
    const shuffled = shuffleArray(allOptions);
    setOptions(shuffled);
  }, [correctAnswer, wrongAnswers]);

  function shuffleArray(array) {
    const newArray = [...array];
    for (let i = newArray.length - 1; i > 0; i--) {
      const j = Math.floor(Math.random() * (i + 1));
      [newArray[i], newArray[j]] = [newArray[j], newArray[i]];
    }
    return newArray;
  }

  const handleOptionClick = (selectedOption) => {
    if (selectedOption === correctAnswer) {
      console.log('回答正确!');
    } else {
      console.log('回答错误!');
    }
  };

  return (
    <div>
      <h3>{question.text}</h3>
      <div className="options">
        {options.map((option, idx) => (
          <button
            key={idx}
            onClick={() => handleOptionClick(option)}
          >
            {option.text}
          </button>
        ))}
      </div>
    </div>
  );
}

关键注意点

  • 避免用sort(() => Math.random() - 0.5)洗牌,这种方法会导致元素出现概率不均,推荐使用Fisher-Yates算法保证随机性公平。
  • Next.js中确保useEffect的依赖项完整,避免因依赖缺失导致的状态更新异常。

内容的提问来源于stack exchange,提问作者Mayowa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 12:20:32