React中动态修改指定单选按钮disabled属性的实现方案
React表单单选按钮按需启用实现方案
核心采用单数据源驱动+配置化渲染的思路实现,无需为每一行单选按钮单独声明状态,也不需要手动操作DOM定位节点修改属性。
具体实现步骤
- 仅维护2个核心全局状态,无冗余状态声明
scannedCode:存储扫码得到的编号值,初始值为nullselectedValue:存储用户最终选中的单选按钮值,初始值为null
- 将所有单选按钮的信息抽离为统一配置数组,每个配置项包含唯一编号(即165开头的匹配值)、对应展示的名称、规格等字段,后续新增选项直接往数组中追加配置项即可
// 单选选项统一配置 const radioOptions = [ { id: '165001', name: '对应物料名称1', spec: '对应规格1' }, { id: '165002', name: '对应物料名称2', spec: '对应规格2' }, { id: '165003', name: '对应物料名称3', spec: '对应规格3' }, // 更多选项可直接追加 ] - 遍历配置数组渲染所有表单行,每个单选按钮的
disabled属性通过行内逻辑直接计算,无需单独存储每个按钮的禁用状态:当scannedCode和当前选项的id完全相等时,按钮为可用状态,其余情况全部保持禁用 - 扫码成功的回调中直接更新
scannedCode状态即可,React的状态驱动机制会自动完成所有按钮的禁用状态更新,精准匹配到对应编号的按钮启用,无需手动查找DOM节点修改属性
完整示例代码
import { useState } from 'react' export default function MaterialForm() { // 仅需2个状态,无逐行声明的冗余代码 const [scannedCode, setScannedCode] = useState(null) const [selectedValue, setSelectedValue] = useState(null) // 扫码成功回调,接收二维码解析出的编号值 const onScanSuccess = (codeResult) => { setScannedCode(codeResult) // 切换扫码结果时清空已选值,避免选中已禁用的选项 setSelectedValue(null) } return ( <div className="form-container"> {/* 扫码组件接入位置,扫码解析完成后调用onScanSuccess传值即可 */} <div className="radio-table"> {radioOptions.map(option => { // 行内计算当前按钮禁用状态 const disabled = scannedCode !== option.id return ( <div key={option.id} className="table-row"> <input type="radio" name="material" value={option.id} disabled={disabled} checked={selectedValue === option.id} onChange={(e) => setSelectedValue(e.target.value)} /> <span className="code-col">{option.id}</span> <span className="name-col">{option.name}</span> <span className="spec-col">{option.spec}</span> </div> ) })} </div> </div> ) }
方案优势
- 状态极简:无论有多少行单选选项,都只需要2个状态,完全避免逐行声明
useState产生的冗余代码 - 更新精准:状态变化时React会自动对比计算每个按钮的禁用状态,匹配编号的按钮会自动启用,不需要手动编写DOM查询、属性修改的逻辑
- 维护成本低:后续新增、删除、修改选项只需要调整
radioOptions配置数组,不需要改动核心交互逻辑
内容的提问来源于stack exchange,提问作者asusrid
相关产品推荐
相关产品推荐

