React中ToggleButton的handleChange如何同时获取ID与Value并设置State
哦,这个问题我碰到过!你这里的核心问题是React-Bootstrap的ToggleButtonGroup组件的onChange回调参数不是DOM事件对象——它直接返回的是选中的value值,所以你之前用e.target.id自然拿不到,因为这里的e其实就是选中的那个value(比如1或2),根本不是事件对象~
下面给你几种实用的解决方案,按推荐程度排序:
方法一:手动传递组ID(直观简单,适合单组按钮)
直接在ToggleButtonGroup的onChange回调里,把对应的FormGroup控制ID(也就是meatOptionDay1)和选中的value一起传给handleChange:
修改render里的ToggleButtonGroup部分:
<ToggleButtonGroup className="btn-choice" type="radio" name="stateofRadio" defaultValue={this.state.radioToggleButton} onChange={(value) => this.handleChange('meatOptionDay1', value)} > <ToggleButton value={1} >Op1</ToggleButton> <ToggleButton value={2}>Op2</ToggleButton> </ToggleButtonGroup>
然后更新handleChange方法,直接接收id和value:
handleChange(id, value){ this.setState({ [id]: value }, () => { // 注意:setState是异步的,必须在回调里才能拿到最新状态 console.log(this.state); }); }
这种方法代码改动最小,逻辑清晰,适合只有单组ToggleButton的场景。
方法二:数据驱动渲染(扩展性强,适合多组按钮)
如果你的页面会有多个ToggleButtonGroup,推荐把按钮配置抽成数组,通过循环渲染,这样不用手动传ID,直接从数据源匹配:
首先在组件里定义配置数据:
// 可以放在组件外部或者constructor中 const toggleGroups = [ { groupId: 'meatOptionDay1', defaultVal: 1, options: [ { value: 1, label: 'Op1' }, { value: 2, label: 'Op2' } ] } ];
然后在render里循环渲染各组按钮:
return( <form onSubmit={this.savePreference}> {toggleGroups.map(group => ( <FormGroup key={group.groupId} controlId={group.groupId} validationState={this.getValidationState()} > <ButtonToolbar> <ToggleButtonGroup className="btn-choice" type="radio" name={group.groupId} defaultValue={group.defaultVal} onChange={(value) => this.handleChange(group.groupId, value)} > {group.options.map(opt => ( <ToggleButton key={opt.value} value={opt.value}>{opt.label}</ToggleButton> ))} </ToggleButtonGroup> </ButtonToolbar> </FormGroup> ))} </form> )
handleChange方法和方法一完全一样,后续新增按钮组只需要修改toggleGroups数组即可,扩展性拉满。
方法三:通过DOM获取ID(应急可用,不推荐)
如果不想改动太多代码,也可以通过DOM查询找到选中的按钮,获取它的ID,但这种方法依赖DOM操作,不符合React的数据流理念,仅作应急:
handleChange(value){ // 根据name属性找到选中的单选按钮 const selectedBtn = document.querySelector('input[name="stateofRadio"]:checked'); if(selectedBtn){ const id = selectedBtn.getAttribute('id'); this.setState({ [id]: value }, () => console.log(this.state)); } }
最后再提醒一句:之前你直接在setState后打印this.state是拿不到最新值的,因为setState是异步更新状态,必须把打印逻辑放在setState的第二个回调参数里才能看到最新的state。
内容的提问来源于stack exchange,提问作者Illep

