React中map处理Hook数组渲染时出现TypeError问题求助
问题分析与解决方案
错误原因
你遇到的Uncaught TypeError: Cannot read properties of undefined (reading 'value'),核心原因是数组结构处理错误:
- 你创建的
answer数组通过answer.push(questions, answers)后,实际结构是[问题对象, 答案数组],而非包含questions和answers属性的对象数组。 - 后续
answer.map(({questions, answers}) => ...)尝试解构每个数组元素的questions属性,但数组里的第一个元素是问题对象本身,第二个是答案数组,两者都没有questions属性,因此questions为undefined,访问questions.value就会触发错误。
此外还有两个次要问题:
- 使用
slice获取错误答案时,slice返回的是数组(比如incorrect_answers.slice(0,1)得到["xxx"]),而非字符串,导致答案按钮显示数组而非文本。 - 冗余的嵌套
map,每个题目只需要渲染一次问题和对应的一组答案,不需要再遍历answer数组。
修正后的代码
import { useState, useEffect } from 'react' import { nanoid } from 'nanoid' import './App.css' import FirstPage from './components/FirstPage' import Quiz from './components/Quiz' function App() { const [startGame, setStartGame] = useState(false) const [quizData, setQuizData] = useState([]) useEffect(() => { fetch(`https://opentdb.com/api.php?amount=5`) .then(res => res.json()) .then(data => setQuizData(data.results)) }, []) function gameStart() { setStartGame(true) } const displayQuestions = quizData.map(({ question, correct_answer, incorrect_answers }) => { // 修正:直接取字符串而非数组,用下标获取错误答案文本 const answer1 = { text: incorrect_answers[0], is_selected: false, is_correct: false, id: nanoid() } const answer2 = { text: incorrect_answers[1], is_selected: false, is_correct: false, id: nanoid() } const answer3 = { text: correct_answer, is_selected: false, is_correct: true, id: nanoid() } const answer4 = { text: incorrect_answers[2], is_selected: false, is_correct: false, id: nanoid() } // 合并所有答案并打乱顺序(可选,让正确答案位置随机) const answers = [answer1, answer2, answer3, answer4].sort(() => Math.random() - 0.5) const questionObj = { value: question, id: nanoid() } // 修正:直接渲染单个问题和对应的答案列表,不需要嵌套map return ( <div key={questionObj.id}> <ul> <li className='questions'>{questionObj.value}</li> {answers.map(answer => ( <button key={answer.id} className='answers'> {answer.text} </button> ))} </ul> </div> ) }) return ( <> <h1 className='bloc'></h1> <h1 className='bloc2'></h1> {startGame ? <Quiz displayQuestions={displayQuestions} /> : <FirstPage gameStart={gameStart} />} </> ) } export default App
关键修正点
- 数组结构调整:不再将问题和答案塞进同一个数组,而是直接为每个题目创建独立的问题对象和答案数组,直接渲染,避免错误的解构操作。
- 修正答案文本获取:用数组下标
incorrect_answers[0]代替slice,直接获取字符串类型的答案文本。 - 可选优化:添加
sort(() => Math.random() - 0.5)打乱答案顺序,让Quiz更符合实际使用场景。 - 移除冗余嵌套map:每个题目对应唯一的问题和答案组,直接渲染即可,无需额外遍历。
内容的提问来源于stack exchange,提问作者Tristanguimard
相关产品推荐
相关产品推荐

