React函数组件循环中如何使用useState及点击切换类名
React函数组件循环场景中用useState实现点击切换类名
核心思路
通过useState记录每个用户的点击状态,点击时更新状态,再结合选项的correct值动态生成对应类名。
具体实现步骤
1. 初始化点击状态
创建状态存储每个用户的选中选项信息,用用户的index作为标识键:
const [selectedAnswers, setSelectedAnswers] = useState({});
2. 编写点击事件处理函数
让处理函数接收用户index和当前选项的correct值,点击时更新状态:
const handleForm = (index, correct) => { setSelectedAnswers(prev => ({ ...prev, [index]: correct })); };
3. 动态生成类名渲染选项
循环渲染时,判断当前用户是否已点击该选项,结合correct值设置类名:
- 未点击时保持基础类名
answer - 已点击时,
correct=1用answer correct,correct=0用js-choose-answer wrong
修改后的完整循环代码:
{users?.map((user, index) => ( <div key={index}> <div onClick={() => handleForm(index, user.opt1 == user.ans ? '1' : '0')} className={ selectedAnswers[index] === (user.opt1 == user.ans ? '1' : '0') ? (user.opt1 == user.ans ? 'answer correct' : 'js-choose-answer wrong') : 'answer' } > <div>a</div>{user.opt1} </div> <div onClick={() => handleForm(index, user.opt2 == user.ans ? '1' : '0')} className={ selectedAnswers[index] === (user.opt2 == user.ans ? '1' : '0') ? (user.opt2 == user.ans ? 'answer correct' : 'js-choose-answer wrong') : 'answer' } > <div>b</div>{user.opt2} </div> <div onClick={() => handleForm(index, user.opt3 == user.ans ? '1' : '0')} className={ selectedAnswers[index] === (user.opt3 == user.ans ? '1' : '0') ? (user.opt3 == user.ans ? 'answer correct' : 'js-choose-answer wrong') : 'answer' } > <div>c</div>{user.opt3} </div> <div onClick={() => handleForm(index, user.opt4 == user.ans ? '1' : '0')} className={ selectedAnswers[index] === (user.opt4 == user.ans ? '1' : '0') ? (user.opt4 == user.ans ? 'answer correct' : 'js-choose-answer wrong') : 'answer' } > <div>d</div>{user.opt4} </div> </div> ))}
4. 可选优化:抽离重复逻辑
把判断correct和类名的逻辑抽成函数,减少代码冗余:
// 抽离判断correct的逻辑 const getCorrectStatus = (opt, ans) => opt == ans ? '1' : '0'; // 抽离类名生成逻辑 const getClassName = (selectedCorrect, currentCorrect) => { if (selectedCorrect === currentCorrect) { return currentCorrect === '1' ? 'answer correct' : 'js-choose-answer wrong'; } return 'answer'; };
优化后的渲染代码:
{users?.map((user, index) => { const selectedCorrect = selectedAnswers[index]; return ( <div key={index}> <div onClick={() => handleForm(index, getCorrectStatus(user.opt1, user.ans))} className={getClassName(selectedCorrect, getCorrectStatus(user.opt1, user.ans))} > <div>a</div>{user.opt1} </div> <div onClick={() => handleForm(index, getCorrectStatus(user.opt2, user.ans))} className={getClassName(selectedCorrect, getCorrectStatus(user.opt2, user.ans))} > <div>b</div>{user.opt2} </div> <div onClick={() => handleForm(index, getCorrectStatus(user.opt3, user.ans))} className={getClassName(selectedCorrect, getCorrectStatus(user.opt3, user.ans))} > <div>c</div>{user.opt3} </div> <div onClick={() => handleForm(index, getCorrectStatus(user.opt4, user.ans))} className={getClassName(selectedCorrect, getCorrectStatus(user.opt4, user.ans))} > <div>d</div>{user.opt4} </div> </div> ); })}
注意事项
- 列表渲染必须添加
key属性,优先使用用户数据的唯一id,无id时可用index - 状态更新使用函数式写法,确保基于最新状态修改
- 若需限制每个用户只能选一次,可在
handleForm中判断selectedAnswers[index]是否已存在,存在则不更新状态
内容的提问来源于stack exchange,提问作者govtexam guru
相关产品推荐
相关产品推荐

