ReactJS ToggleButtonGroup(radio类型)onChange事件无法触发的问题与解决
我之前也碰到过一模一样的问题——用React Bootstrap的Radio类型ToggleButtonGroup时,死活触发不了onChange事件。看了你的代码,问题主要出在事件绑定的方式和受控组件的用法上,下面是梳理的问题分析和最终可行的解决方案:
初始代码问题分析
你一开始的实现里有两个关键问题:
- 同时在
ToggleButtonGroup和每个子ToggleButton上绑定了onChange,这会导致事件冒泡和逻辑冲突。React Bootstrap的ToggleButtonGroup作为容器组件,应该统一在容器上处理选中变化,而非给每个按钮单独加事件。 - 受控模式下的
ToggleButtonGroup不应该使用defaultChecked,受控组件的选中状态完全由value属性控制,defaultChecked是非受控组件的用法。
你的初始实现代码如下:
class ToggleButtonGroupControlled extends React.Component { constructor(props, context) { super(props, context); //this.handleChange = this.handleChange.bind(this); this.state = { value: 1 }; } handleChange(e) { console.log(e); this.setState({ value: e }); } render() { return ( <ToggleButtonGroup type="radio" name="exemption_status_button" value={this.state.value} onChange={this.handleChange.bind(this)} defaultChecked={this.state.value} > <ToggleButton onChange={this.handleChange} value={1} className="badge2" data-count={this.props.statusButton.requested}>Requested</ToggleButton> <ToggleButton onChange={this.handleChange} value={3} className="badge2" data-count={this.props.statusButton.accepted}>Accepted</ToggleButton> <ToggleButton onChange={this.handleChange} value={6} className="badge2" data-count={this.props.statusButton.implemented}>Implemented</ToggleButton> <ToggleButton onChange={this.handleChange} value={5} className="badge2" data-count={this.props.statusButton.cancelled}>Cancelled</ToggleButton> <ToggleButton onChange={this.handleChange} value={4} className="badge2" data-count={this.props.statusButton.rejected}>Rejected</ToggleButton> </ToggleButtonGroup> ); } }
解决方案
我通过改用onClick事件结合jQuery获取实际选中的radio值,同时调整了状态传递逻辑,成功解决了事件不触发的问题。核心调整点:
- 统一在子按钮上绑定
onClick事件,避免容器和子组件的事件冲突 - 通过jQuery直接获取底层radio input的选中值(React Bootstrap的ToggleButton会渲染成包含input的嵌套结构)
- 新增回调方法将选中值传递给父组件,满足业务的状态同步需求
最终的可行代码如下:
import _ from 'lodash'; import axios from 'axios'; import React, { Component } from 'react'; import { Checkbox } from 'react-bootstrap'; import { connect } from 'react-redux'; import { fetchSecurityExemptions, fetchSecurityExemptionsCount, fetchMarkets, fetchServiceDomains, fetchServicesList, fetchSecurityEngineerList, fetchBusinessPriorityList, updateSecurityExemption } from '../../actions/security'; import { bindActionCreators } from 'redux'; import { Button, ButtonToolbar, Modal, Tooltip, OverlayTrigger, ToggleButton, ToggleButtonGroup } from 'react-bootstrap'; import FontAwesome from 'react-fontawesome'; import { BootstrapTable, TableHeaderColumn, InsertModalHeader, InsertModalFooter, SearchField } from 'react-bootstrap-table'; import 'react-bootstrap-table/dist/react-bootstrap-table-all.min.css'; import $ from 'jquery'; import ModalError from '../modalerror'; import ModalConfirm from '../modalconfirm'; import { Link } from 'react-router-dom'; import { isGenericName } from '../../scripts/validation'; class ToggleButtonGroupControlled extends Component { constructor(props, context) { super(props, context); this.handleChange = this.handleChange.bind(this); this.value = 1 } handleChange(e) { this.value = $(e.target).children('input').val(); this.passStatusButtonBack(); } passStatusButtonBack(){ this.props.passStatusButtonBack(this.value); } render() { return ( <ButtonToolbar> <ToggleButtonGroup type="radio" name="exemption_status_button" value={this.value} onChange={this.handleChange} defaultChecked={this.value} > <ToggleButton onClick={this.handleChange} value={1} className="badge2" data-count={this.props.statusButton.requested}>Requested</ToggleButton> <ToggleButton onClick={this.handleChange} value={3} className="badge2" data-count={this.props.statusButton.accepted}>Accepted</ToggleButton> <ToggleButton onClick={this.handleChange} value={6} className="badge2" data-count={this.props.statusButton.implemented}>Implemented</ToggleButton> <ToggleButton onClick={this.handleChange} value={5} className="badge2" data-count={this.props.statusButton.cancelled}>Cancelled</ToggleButton> <ToggleButton onClick={this.handleChange} value={4} className="badge2" data-count={this.props.statusButton.rejected}>Rejected</ToggleButton> </ToggleButtonGroup> </ButtonToolbar> ); } }
内容的提问来源于stack exchange,提问作者shorif2000
相关产品推荐
相关产品推荐

