You need to enable JavaScript to run this app. 如何映射题目类对象?遇answerOptions未定义及DND拖拽splice问题
优惠活动
大模型
产品
解决方案
定价
更多

如何映射题目类对象?遇answerOptions未定义及DND拖拽splice问题

报错根因
  • 初始数据源存在语法错误:原结构中第二个选项的result字段值为未定义的correctAnswer引用,JS执行初始化时就会直接抛出ReferenceError,导致后续访问路径断裂。
  • 变量名大小写不匹配:代码中访问的是大写开头的Questions,但定义的初始数组为小写的questions,JS严格区分大小写时就会直接获取到undefined,自然读不到后续的answerOptions属性。
  • 拖拽splice操作层级错误:更新数组时没有按题目对象 -> answerOptions的层级做不可变更新,要么直接覆盖了当前题目对象、要么currentQuestion索引越界,最终导致取到的题目对象上没有answerOptions字段。
修复方案

1. 修正初始数据源的语法问题

删除未定义的correctAnswer引用,给每个选项的result字段设置统一的空初始值:

const questions = [
  {
    id:1,
    questionText: 'W którym roku firma apple wprowadziła do sprzedaży pierwszy komputer?',
    answerOptions: [
      { id: 1, answerText: 'A.1974', isCorrect: false, result: [] },
      { id: 2, answerText: 'B.1976', isCorrect: true, result: [] },
      { id: 3, answerText: 'C.1984', isCorrect: false, result: [] },
      { id: 4, answerText: 'D.1990', isCorrect: false, result: [] },
    ],
  }
]

2. 修正映射逻辑的取值路径

匹配正确的变量名,加上*可选链?.*做兜底,避免索引越界、对象不存在时直接抛出属性访问错误:

// 注意变量名和定义的questions保持一致,全部小写
questions?.[currentQuestion]?.answerOptions?.map(
  ({ id, answerText, isCorrect, result }, index) => {
    return (
      <Draggable
        key={`draggable2-${id}`}
        draggableId={`draggable2-${id}`}
        index={index}
      >
        {(provided, snapshot) => {
          return (
            <div
              ref={provided.innerRef}
              {...provided.draggableProps}
              {...provided.dragHandleProps}
            >
              <div
                className="answer"
                onClick={() => handleAnswerClick(isCorrect)}
              >
                <div className="answerText">{answerText}</div>
                <div className={resultCorrect}>{result}</div>
              </div>
            </div>
          );
        }}
      </Draggable>
    );
  }
)

3. 修正拖拽排序的splice操作逻辑

不要直接在原state上做原地修改,严格按照「复制题目对象->复制answerOptions数组->执行splice排序->把排序结果挂回题目对象->回写整个state数组」的层级更新,避免弄丢answerOptions字段:

const onDragEnd = (result) => {
  const { source, destination } = result;
  // 无有效落点时直接返回,不执行操作
  if (!destination) return;

  setQuestions(prev => {
    // 先拿到当前题目的浅拷贝,避免直接修改原对象
    const copiedCurrentQuestion = {...prev[currentQuestion]};
    // 拷贝answerOptions数组,不直接在原数组上splice
    const copiedAnswerList = Array.from(copiedCurrentQuestion.answerOptions);
    // 执行元素移动
    const [movedItem] = copiedAnswerList.splice(source.index, 1);
    copiedAnswerList.splice(destination.index, 0, movedItem);
    // 把排序后的列表挂回拷贝的题目对象
    copiedCurrentQuestion.answerOptions = copiedAnswerList;
    // 把更新后的题目放回外层数组,生成新的state
    const newQuestionList = Array.from(prev);
    newQuestionList[currentQuestion] = copiedCurrentQuestion;
    return newQuestionList;
  })
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.24 22:15:08