React Native中如何修改数组指定索引的值(测验场景)
实现测验程序的完整方案
嘿,这需求我熟!咱们一步步来搞定这个支持切换题目、修改指定索引答案的测验程序,核心是状态管理和数组的不可变更新,我给你拆解清楚:
1. 核心状态设计
首先除了存储答案的answer数组,咱们还需要一个currentIndex状态来跟踪当前显示的题目位置——毕竟切换上下题和修改答案都依赖它。如果题目数量固定,初始化时直接把answer设为对应长度的空数组会更省心:
// 类组件版本的初始状态 this.state = { answer: new Array(3).fill(''), // 假设总共有3道题,你可以根据实际调整数量 currentIndex: 0 // 默认显示第一题 }; // 函数组件版本(用React Hooks) const totalQuestions = 3; const [answer, setAnswer] = useState(new Array(totalQuestions).fill('')); const [currentIndex, setCurrentIndex] = useState(0);
2. 实现上一题/下一题切换
切换逻辑很简单:修改currentIndex,但要做好边界判断,防止索引越界(比如不能从第1题再切上一题,也不能从最后一题切下一题):
// 类组件版本 handlePrev = () => { this.setState(prevState => ({ currentIndex: Math.max(prevState.currentIndex - 1, 0) })); }; handleNext = () => { const totalQuestions = 3; this.setState(prevState => ({ currentIndex: Math.min(prevState.currentIndex + 1, totalQuestions - 1) })); }; // 函数组件版本 const handlePrev = () => { setCurrentIndex(prev => Math.max(prev - 1, 0)); }; const handleNext = () => { setCurrentIndex(prev => Math.min(prev + 1, totalQuestions - 1)); };
3. 修改指定索引的答案
这里要注意React状态不可直接修改,必须创建数组的副本,修改副本后再更新状态,否则React检测不到变化不会重新渲染。咱们写一个处理答案变更的函数:
// 类组件版本 handleAnswerChange = (selectedAnswer) => { this.setState(prevState => { // 复制原answer数组,避免直接修改原state const newAnswer = [...prevState.answer]; // 给当前索引的位置赋值新答案 newAnswer[prevState.currentIndex] = selectedAnswer; return { answer: newAnswer }; }); }; // 函数组件版本 const handleAnswerChange = (selectedAnswer) => { setAnswer(prev => { const newAnswer = [...prev]; newAnswer[currentIndex] = selectedAnswer; return newAnswer; }); };
完整示例代码(函数组件)
我给你写一个可直接运行的完整组件,包含题目选项渲染、切换按钮和答案实时展示:
import { useState } from 'react'; function QuizApp() { const totalQuestions = 3; // 模拟题目列表,你可以换成自己的题目内容 const questions = [ { title: "第一题:选择正确选项", options: ["a", "b", "c"] }, { title: "第二题:选择正确选项", options: ["a", "b", "c"] }, { title: "第三题:选择正确选项", options: ["a", "b", "c"] } ]; const [answer, setAnswer] = useState(new Array(totalQuestions).fill('')); const [currentIndex, setCurrentIndex] = useState(0); const handlePrev = () => { setCurrentIndex(prev => Math.max(prev - 1, 0)); }; const handleNext = () => { setCurrentIndex(prev => Math.min(prev + 1, totalQuestions - 1)); }; const handleAnswerChange = (selectedAnswer) => { setAnswer(prev => { const newAnswer = [...prev]; newAnswer[currentIndex] = selectedAnswer; return newAnswer; }); }; return ( <div style={{ padding: '20px', maxWidth: '500px', margin: '0 auto' }}> <h2>测验程序</h2> <div className="question-card"> <h3>{questions[currentIndex].title}</h3> <div style={{ margin: '15px 0' }}> {questions[currentIndex].options.map(opt => ( <label key={opt} style={{ display: 'block', margin: '8px 0' }}> <input type="radio" value={opt} checked={answer[currentIndex] === opt} onChange={() => handleAnswerChange(opt)} /> 选项 {opt.toUpperCase()} </label> ))} </div> </div> <div style={{ display: 'flex', gap: '10px', margin: '20px 0' }}> <button onClick={handlePrev} disabled={currentIndex === 0} style={{ padding: '8px 16px' }}> 上一题 </button> <button onClick={handleNext} disabled={currentIndex === totalQuestions - 1} style={{ padding: '8px 16px' }}> 下一题 </button> </div> <div style={{ padding: '10px', backgroundColor: '#f0f0f0', borderRadius: '4px' }}> <p>当前答案数组:<code>{JSON.stringify(answer)}</code></p> </div> </div> ); } export default QuizApp;
关键注意点
- 不可变更新:永远不要直接修改
this.state.answer或者answer数组,必须通过复制新数组的方式修改,否则React无法感知状态变化,页面不会更新。 - 边界控制:切换题目时一定要限制
currentIndex的范围,避免出现索引越界导致的错误。 - 数组初始化:提前初始化对应题目数量的空数组,能让每道题的答案和索引直接对应,比动态添加元素更清晰。
内容的提问来源于stack exchange,提问作者Shyfa Andiantono
相关产品推荐
相关产品推荐

