React中如何将迭代值存入state数组并展示问答内容
问题:遍历数据集后State仅保存最后一条问题/答案
我正在遍历数据集中的每个问题,希望将每次迭代的值存入数组并保存到state中,从而获取所有问题的数组。目前控制台能依次打印每个问题,但state中仅存储了一个问题,想要展示所有问题及其对应的答案却不知道怎么实现。
数据集结构
[ { "id":1, "question":"...", "answers":[ {"id":1,"answer":"..."}, {"id":2,"answer":"..."} ] }, { "id":2, "question":"...", "answers":[ {"id":1,"answer":""}, {"id":2,"answer":""}, {"id":3,"answer":""} ] } ... ]
我的代码
// the entire data set const [questionsData, setQuestionsData] = useState<any>([]) // the actual questions const [questions, setQuestions] = useState<[]>([]) const [answers, setAnswers] = useState<[]>([]) useEffect(() => { fetch("/...") .then((response) => response.json()) .then((data) => setQuestionsData(data)) }, []); useEffect(() => { if (questionsData.length > 0) { for (let i = 0, l = questionsData.length; i < l; i++) { setAnswers(questionsData[i].answers) setQuestions(questionsData[i].question) console.log(questionsData[i].question) } } }, [questionsData, answers]) return ( <p>{JSON.stringify(questions)}</p> <p>{JSON.stringify(answers)}</p> )
问题原因
- 循环中setState覆盖值:每次循环调用
setQuestions和setAnswers都是直接赋值当前项的内容,React的state更新是异步批量处理的,循环结束后只会保留最后一次赋值的结果,所以最终state里只有最后一条问题和答案。 - 无限循环风险:
answers被加入了第二个useEffect的依赖项,每次调用setAnswers都会触发这个useEffect重新执行,导致循环调用。
解决方案
方案一:直接基于原数据集渲染(推荐)
原数据结构已经包含每个问题对应的答案数组,不需要拆分单独维护questions和answers的state,直接遍历questionsData即可:
const [questionsData, setQuestionsData] = useState<any>([]) useEffect(() => { fetch("/...") .then((response) => response.json()) .then((data) => setQuestionsData(data)) }, []); return ( <div className="questions-container"> {questionsData.map((item) => ( <div key={item.id} className="question-item"> <h4>{item.question}</h4> <div className="answers-list"> {item.answers.map((answer) => ( <p key={answer.id}>- {answer.answer}</p> ))} </div> </div> ))} </div> )
方案二:一次性提取所有问题和答案存入state
如果需要单独处理问题或答案的格式,可以在获取数据后一次性提取所有内容,避免循环中多次setState:
const [questionsData, setQuestionsData] = useState<any>([]) const [questions, setQuestions] = useState<string[]>([]) const [allAnswers, setAllAnswers] = useState<any[][]>([]) useEffect(() => { fetch("/...") .then((response) => response.json()) .then((data) => { setQuestionsData(data) // 一次性提取所有问题和对应答案数组 const allQuestions = data.map(item => item.question) const allAnswersArray = data.map(item => item.answers) setQuestions(allQuestions) setAllAnswers(allAnswersArray) }) }, []); return ( <div> <h3>所有问题</h3> {questions.map((q, index) => ( <div key={index}> <p>{index + 1}. {q}</p> <div>对应答案:</div> <ul> {allAnswers[index].map(answer => ( <li key={answer.id}>{answer.answer}</li> ))} </ul> </div> ))} </div> )
内容的提问来源于stack exchange,提问作者SK1dev
相关产品推荐
相关产品推荐

