ReactJS中如何实现点击单个按钮切换两个按钮的不同背景色?
React YES/NO 选择题交互实现方案
需求
- 每组选择题包含YES和NO两个按钮
- 点击YES:YES按钮背景变绿色,NO按钮背景变红色
- 点击NO:NO按钮背景变绿色,YES按钮背景变红色
- 核心规则:选中的按钮显示绿色,未选中的显示红色
现有代码片段
<div className="fcontainer"> <div className="fitem"> Did You come into the pharmacy today for Medicine? </div> <div className="fitem"> <button> No</button> <button>Yes</button> </div> </div> <hr /> <div> <h5>Where do you asked any of the following:</h5> <div style={{ marginTop: "10px" }}> <div className="fcontainer"> <div className="fitem ques">Who is the Medicine for?</div> <div className="fitem "> <button className="butn">No</button> <button className="butn">Yes</button> </div> </div> <div className="fcontainer"> <div className="fitem ques">What are yours symptoms?</div> <div className="fitem"> <button className="butn">No</button> <button className="butn">Yes</button> </div> </div> <div className="fcontainer"> <div className="fitem ques"> How long you had the symptoms? </div> <div className="fitem"> <button className="butn">No</button> <button className="butn">Yes</button> </div> </div> <div className="fcontainer"> <div className="fitem ques"> What action have you already taken? </div> <div className="fitem"> <button className="butn">No</button> <button className="butn">Yes</button> </div> </div> <div className="fcontainer"> <div className="fitem ques"> Are you taking any other medication? </div> <div className="fitem"> <button className="butn">No</button> <button className="butn">Yes</button> </div> </div> </div> </div>
完整实现代码
React 组件代码(App.jsx)
import { useState } from 'react'; import './App.css'; function App() { // 存储每道题的选择结果,key为题目标识,值为'yes'/'no'或null(未选择) const [answers, setAnswers] = useState({ pharmacyVisit: null, medicineFor: null, symptoms: null, symptomDuration: null, takenActions: null, otherMedication: null }); // 处理按钮点击,更新对应题目的选择 const handleAnswer = (questionKey, choice) => { setAnswers(prevAnswers => ({ ...prevAnswers, [questionKey]: choice })); }; return ( <div className="app-container"> {/* 第一题 */} <div className="fcontainer"> <div className="fitem"> Did You come into the pharmacy today for Medicine? </div> <div className="fitem"> <button className={`butn ${answers.pharmacyVisit === 'no' ? 'selected-green' : answers.pharmacyVisit === 'yes' ? 'unselected-red' : ''}`} onClick={() => handleAnswer('pharmacyVisit', 'no')} > No</button> <button className={`butn ${answers.pharmacyVisit === 'yes' ? 'selected-green' : answers.pharmacyVisit === 'no' ? 'unselected-red' : ''}`} onClick={() => handleAnswer('pharmacyVisit', 'yes')} >Yes</button> </div> </div> <hr /> {/* 第二组题目 */} <div> <h5>Were you asked any of the following:</h5> <div style={{ marginTop: "10px" }}> {/* 子题1 */} <div className="fcontainer"> <div className="fitem ques">Who is the Medicine for?</div> <div className="fitem "> <button className={`butn ${answers.medicineFor === 'no' ? 'selected-green' : answers.medicineFor === 'yes' ? 'unselected-red' : ''}`} onClick={() => handleAnswer('medicineFor', 'no')} >No</button> <button className={`butn ${answers.medicineFor === 'yes' ? 'selected-green' : answers.medicineFor === 'no' ? 'unselected-red' : ''}`} onClick={() => handleAnswer('medicineFor', 'yes')} >Yes</button> </div> </div> {/* 子题2 */} <div className="fcontainer"> <div className="fitem ques">What are your symptoms?</div> <div className="fitem"> <button className={`butn ${answers.symptoms === 'no' ? 'selected-green' : answers.symptoms === 'yes' ? 'unselected-red' : ''}`} onClick={() => handleAnswer('symptoms', 'no')} >No</button> <button className={`butn ${answers.symptoms === 'yes' ? 'selected-green' : answers.symptoms === 'no' ? 'unselected-red' : ''}`} onClick={() => handleAnswer('symptoms', 'yes')} >Yes</button> </div> </div> {/* 子题3 */} <div className="fcontainer"> <div className="fitem ques">How long have you had the symptoms?</div> <div className="fitem"> <button className={`butn ${answers.symptomDuration === 'no' ? 'selected-green' : answers.symptomDuration === 'yes' ? 'unselected-red' : ''}`} onClick={() => handleAnswer('symptomDuration', 'no')} >No</button> <button className={`butn ${answers.symptomDuration === 'yes' ? 'selected-green' : answers.symptomDuration === 'no' ? 'unselected-red' : ''}`} onClick={() => handleAnswer('symptomDuration', 'yes')} >Yes</button> </div> </div> {/* 子题4 */} <div className="fcontainer"> <div className="fitem ques">What action have you already taken?</div> <div className="fitem"> <button className={`butn ${answers.takenActions === 'no' ? 'selected-green' : answers.takenActions === 'yes' ? 'unselected-red' : ''}`} onClick={() => handleAnswer('takenActions', 'no')} >No</button> <button className={`butn ${answers.takenActions === 'yes' ? 'selected-green' : answers.takenActions === 'no' ? 'unselected-red' : ''}`} onClick={() => handleAnswer('takenActions', 'yes')} >Yes</button> </div> </div> {/* 子题5 */} <div className="fcontainer"> <div className="fitem ques">Are you taking any other medication?</div> <div className="fitem"> <button className={`butn ${answers.otherMedication === 'no' ? 'selected-green' : answers.otherMedication === 'yes' ? 'unselected-red' : ''}`} onClick={() => handleAnswer('otherMedication', 'no')} >No</button> <button className={`butn ${answers.otherMedication === 'yes' ? 'selected-green' : answers.otherMedication === 'no' ? 'unselected-red' : ''}`} onClick={() => handleAnswer('otherMedication', 'yes')} >Yes</button> </div> </div> </div> </div> </div> ); } export default App;
样式文件(App.css)
/* 基础按钮样式 */ .butn { padding: 8px 16px; margin: 0 8px; border: none; border-radius: 4px; cursor: pointer; transition: background-color 0.2s ease; } /* 选中状态(绿色) */ .selected-green { background-color: #4CAF50; color: #fff; } /* 未选中状态(红色) */ .unselected-red { background-color: #f44336; color: #fff; } /* 布局样式 */ .fcontainer { display: flex; justify-content: space-between; align-items: center; margin-bottom: 16px; padding: 0 8px; } .fitem { flex: 1; } .fitem.ques { margin-right: 16px; text-align: left; } .app-container { max-width: 800px; margin: 20px auto; padding: 0 16px; }
关键实现说明
- 状态管理:用
useState创建一个对象状态,每个属性对应一道题的选择结果,确保每道题的状态独立,互不干扰。 - 通用点击事件:写一个
handleAnswer函数,通过动态属性名更新对应题目的状态,避免重复写多个事件处理函数。 - 动态样式绑定:根据当前题目的选择结果,给按钮添加对应的样式类,实现选中/未选中的视觉区分。
- 布局优化:保留原有布局类的同时,添加基础容器样式,让页面更美观。
内容的提问来源于stack exchange,提问作者Abdul Rehman
相关产品推荐
相关产品推荐

