React中如何向事件处理函数传参?复用Dropdown逻辑方案
统一处理Reactstrap Dropdown的重复事件逻辑
这问题我太懂了!你现在写的每个Dropdown都单独写toggle和select函数,确实越加越冗余。咱们可以通过给事件处理函数传递唯一标识参数的方式,把重复逻辑抽成通用函数,以后加多少Dropdown都不用复制代码啦!
第一步:重构State结构,让它更可扩展
原来的state是每个Dropdown单独存状态,咱们改成按Dropdown的标识(比如photo、doc)来分组,这样新增Dropdown只需要在初始state里加个键值对就行:
this.state = { // 存每个Dropdown的展开状态 dropdownOpen: { photo: false, doc: false }, // 存每个Dropdown的选中值 selectedValues: { photo: "រូបថត", doc: "រូបថត" } };
第二步:编写通用的事件处理函数
把原来的togglePhoto、toggleDoc合并成一个toggleDropdown,selectPhoto、selectDoc合并成selectDropdown,通过传入的标识来区分要操作哪个Dropdown:
// 通用的展开/收起函数 toggleDropdown(dropdownKey) { this.setState(prevState => ({ dropdownOpen: { ...prevState.dropdownOpen, [dropdownKey]: !prevState.dropdownOpen[dropdownKey] } })); } // 通用的选中项处理函数 selectDropdown(event, dropdownKey) { const selectedText = event.target.innerText; this.setState(prevState => ({ dropdownOpen: { ...prevState.dropdownOpen, [dropdownKey]: !prevState.dropdownOpen[dropdownKey] }, selectedValues: { ...prevState.selectedValues, [dropdownKey]: selectedText } })); }
这里用了函数式更新state(prevState),因为新状态依赖于之前的状态,这样更安全;还用到了计算属性名([dropdownKey]),根据传入的标识动态更新对应的状态字段。
第三步:修改Render里的Dropdown组件调用
把原来的单独函数换成通用函数,并且传递对应的标识参数:
// Photo的Dropdown <ButtonDropdown isOpen={this.state.dropdownOpen.photo} toggle={() => this.toggleDropdown('photo')} > <DropdownToggle caret>{this.state.selectedValues.photo}</DropdownToggle> <DropdownMenu> <DropdownItem onClick={(e) => this.selectDropdown(e, 'photo')}>ថតថ្មីពីកាមេរា</DropdownItem> <DropdownItem onClick={(e) => this.selectDropdown(e, 'photo')}>ដាក់រូបដែលមានស្រាប់</DropdownItem> </DropdownMenu> </ButtonDropdown> // Doc的Dropdown <ButtonDropdown isOpen={this.state.dropdownOpen.doc} toggle={() => this.toggleDropdown('doc')} > <DropdownToggle caret>{this.state.selectedValues.doc}</DropdownToggle> <DropdownMenu> <DropdownItem onClick={(e) => this.selectDropdown(e, 'doc')}>ថតថ្មីពីកាមេរា</DropdownItem> <DropdownItem onClick={(e) => this.selectDropdown(e, 'doc')}>ដាក់រូបដែលមានស្រាប់</DropdownItem> </DropdownMenu> </ButtonDropdown>
第四步:新增Dropdown超简单!
以后要加新的Dropdown,比如叫idCard,只需要两步:
- 在初始state里加对应字段:
this.state = { dropdownOpen: { photo: false, doc: false, idCard: false // 新增的Dropdown状态 }, selectedValues: { photo: "រូបថត", doc: "រូបថត", idCard: "អត្តសញ្ញាណប័ណ្ណ" // 新增的默认值 } };
- 直接复用通用函数渲染Dropdown:
<ButtonDropdown isOpen={this.state.dropdownOpen.idCard} toggle={() => this.toggleDropdown('idCard')} > <DropdownToggle caret>{this.state.selectedValues.idCard}</DropdownToggle> <DropdownMenu> <DropdownItem onClick={(e) => this.selectDropdown(e, 'idCard')}>ថតថ្មីពីកាមេរា</DropdownItem> <DropdownItem onClick={(e) => this.selectDropdown(e, 'idCard')}>ដាក់រូបដែលមានស្រាប់</DropdownItem> </DropdownMenu> </ButtonDropdown>
这样一来,不管加多少个Dropdown,都不用再写新的事件处理函数啦,代码一下子就清爽很多!
内容的提问来源于stack exchange,提问作者tree em
相关产品推荐
相关产品推荐

