ReactJS Patternfly类组件多Dropdown下拉框重复代码优化咨询
重构方案
1. 统一状态结构
把零散的下拉框状态聚合为一个对象存储,用唯一标识区分不同下拉框,后续新增下拉框只需要在对象里新增对应配置即可,不需要单独声明三类状态:
// 初始state this.state = { selectMap: { // key为下拉框唯一标识,值为对应状态 timeRange: { isOpen: false, selected: null, isDisabled: false }, timeRange1: { isOpen: false, selected: null, isDisabled: false } // 后续新增下拉框只需要在这里加对应key的配置即可 } }
2. 复用公共处理方法
所有下拉框共用一套处理逻辑,通过传入的下拉框唯一标识定位要更新的状态:
// 构造函数内定义,所有下拉框通用 this.optionsMap = { timeRange: [ <SelectOption key={0} value={hourTxt} isPlaceholder />, <SelectOption key={1} value={weekTxt} />, <SelectOption key={2} value={dayTxt} />, <SelectOption key={3} value={neverTxt} />, ], timeRange1: [ <SelectOption key={0} value={hourTxt} />, <SelectOption key={1} value={weekTxt} />, <SelectOption key={2} value={dayTxt} isPlaceholder />, <SelectOption key={3} value={neverTxt} />, ] } // 通用切换方法 this.onToggle = (dropdownKey, isOpen) => { this.setState(prev => ({ selectMap: { ...prev.selectMap, [dropdownKey]: { ...prev.selectMap[dropdownKey], isOpen } } })) } // 通用选择方法 this.onSelect = (dropdownKey, event, selection, isPlaceholder) => { if (isPlaceholder) { this.clearSelection(dropdownKey) return } this.setState(prev => ({ selectMap: { ...prev.selectMap, [dropdownKey]: { ...prev.selectMap[dropdownKey], selected: selection, isOpen: false } } }), () => { this.postSelectData() }) } // 通用清空方法 this.clearSelection = (dropdownKey) => { this.setState(prev => ({ selectMap: { ...prev.selectMap, [dropdownKey]: { ...prev.selectMap[dropdownKey], selected: null, isOpen: false } } }), () => { this.postSelectData() }) }
3. 渲染时绑定对应参数
在render中调用方法时传入对应下拉框的唯一标识即可:
// render内取值 const { selectMap } = this.state // return内渲染 <Select variant={SelectVariant.single} onToggle={(isOpen) => this.onToggle('timeRange', isOpen)} onSelect={(e, selection, isPlaceholder) => this.onSelect('timeRange', e, selection, isPlaceholder)} selections={selectMap.timeRange.selected} isOpen={selectMap.timeRange.isOpen} isDisabled={selectMap.timeRange.isDisabled} > {this.optionsMap.timeRange} </Select> <Select variant={SelectVariant.single} onToggle={(isOpen) => this.onToggle('timeRange1', isOpen)} onSelect={(e, selection, isPlaceholder) => this.onSelect('timeRange1', e, selection, isPlaceholder)} selections={selectMap.timeRange1.selected} isOpen={selectMap.timeRange1.isOpen} isDisabled={selectMap.timeRange1.isDisabled} > {this.optionsMap.timeRange1} </Select>
扩展说明
后续新增下拉框只需要做三步:
- 在state的selectMap中新增对应key的初始状态
- 在optionsMap中新增对应key的选项配置
- 复制一份Select组件,修改传入的标识key即可,不需要新增任何处理方法。
内容的提问来源于stack exchange,提问作者Arun Kumar
相关产品推荐
相关产品推荐

