React+Hydrogen单选按钮选中状态背景色切换问题求助
问题需求
实现单选按钮组的选中背景色切换功能,每组仅允许选中一个选项。例如点击「White」后,「Black」不能保持选中背景色;选择尺寸「L」后点击「S」,「L」恢复默认背景色,「S」变为选中状态的背景色。
当前尝试的代码
{values.map((value) => { const id = `option-${name}-${value}`; const checked = selectedOption[name] === value; // 原代码此处笔误,修正为selectedOption[name] const [bgSelected, setBgSelected] = useState(false); const handleClick = () => { setBgSelected(!bgSelected); } const handleSelected = () => { setSelectedOption(name, value); if (bgSelected === true) { setBgSelected(false); handleClick() } else { setBgSelected(true); handleClick() } } return ( <div key={id} className="product-option-value text-left"> <div type="button" checked={checked} name={name} value={value} id={id} // onChange={() =>setSelectedOption(name, value)} className="" /> <label htmlFor={id} //onClick={handleClick} className={bgSelected ? "bg-blue-800" : "bg-blue-200"} onClick={handleSelected} >{value}</label> </div> ) })} </div>
解决方案
核心问题是每个选项单独维护本地bgSelected状态,导致组内选项状态无法联动。正确做法是用全局的selectedOption统一控制所有选项的选中状态,无需每个选项自己的本地状态。
关键改动点:
- 移除本地状态:删掉每个选项内部的
const [bgSelected, setBgSelected] = useState(false);,所有选中状态由selectedOption管理。 - 统一判断选中状态:用
const isSelected = selectedOption[name] === value;判断当前选项是否被选中。 - 简化点击逻辑:点击时只更新全局的
selectedOption,无需处理本地状态。 - 绑定背景色到全局状态:label的className直接用
isSelected切换样式。
修改后的完整代码示例
假设selectedOption是用useState定义的对象(如const [selectedOption, setSelectedOption] = useState({});),修改后的代码如下:
{values.map((value) => { const id = `option-${name}-${value}`; // 用全局状态判断当前选项是否选中 const isSelected = selectedOption[name] === value; // 点击时更新全局选中状态 const handleSelected = () => { setSelectedOption(prev => ({ ...prev, [name]: value // 按组名存储选中值,比如color: 'White',size: 'S' })); }; return ( <div key={id} className="product-option-value text-left"> {/* 用原生radio input,借助name属性实现原生单选逻辑 */} <input type="radio" checked={isSelected} name={name} value={value} id={id} className="sr-only" // 隐藏原生input,仅展示label交互 onChange={handleSelected} /> <label htmlFor={id} className={`${isSelected ? "bg-blue-800" : "bg-blue-200"} cursor-pointer`} >{value}</label> </div> ) })} </div>
说明:
- 原生
radio的name属性会自动保证同组仅能选中一个,无需额外逻辑。 - 用
sr-only类隐藏原生input,仅保留label作为交互元素,兼顾语义和视觉需求。 - 所有选中状态由
selectedOption对象统一管理,组内选项状态自动联动。
内容的提问来源于stack exchange,提问作者imnotremi
相关产品推荐
相关产品推荐

