SPFX中Fluent UI React Dropdown更新后选中值丢失但状态留存问题
问题原因
- 首要原因是
this.props.companyOptions的key值类型和state.companyDropDownSelected的类型不匹配:Fluent UI Dropdown的selectedKey是严格匹配类型的,如果你存在companyOptions的key是number类型,但是state里存的是强制转换后的string类型的情况,就会识别不到对应选项,显示为空。修改WebPart属性面板触发props更新后,Dropdown会重新执行选中项匹配逻辑,就会出现原有选中值消失的问题。 - 次要原因是事件处理的重复绑定:
onCompanyChange已经用了箭头函数的类属性写法,本身就自动绑定了this,不需要在constructor里再执行bind(this),多余的绑定可能在props更新时触发异常的重新渲染。 - 特殊情况是SPFX属性面板修改后,父层重新传递的
companyOptions是新生成的数组引用,没有做稳定化处理,触发Dropdown的重初始化。
解决步骤
1. 统一key的类型
去掉onCompanyChange里强制转string的逻辑,保持和companyOptions里key的原始类型一致:
public onCompanyChange = async (event: React.FormEvent<HTMLDivElement>, item: IDropdownOption): Promise<void> => { const selectedKey = item ? item.key : ""; this.setState({ companyDropDownSelected: selectedKey }); this.fetchParts(); }
同时调整state初始化的类型,如果你的companyOptions的key是number类型,初始值改成0或者null,不要用空字符串。
2. 移除多余的绑定
把constructor里的this.onCompanyChange = this.onCompanyChange.bind(this);这行代码删除,箭头函数类属性已经自带this绑定,重复绑定会导致props更新时事件引用变化,触发Dropdown不必要的重渲染。
3. 增加props更新时的状态校验(可选)
如果上述两步未解决问题,在componentDidUpdate里加一层判断,校验当前选中的key是否存在于最新的companyOptions里,不存在才重置:
public componentDidUpdate(prevProps: IOrderingProps, prevState: ICurrentWpState, prevContext: any): void { // 仅limit变化时重新拉取数据 if (this.props.limit !== prevProps.limit) { this.fetchParts(); } // 校验选中key是否在最新选项列表中 const hasSelectedKey = this.props.companyOptions.some(opt => opt.key === this.state.companyDropDownSelected); if (!hasSelectedKey) { this.setState({companyDropDownSelected: ""}); } }
4. 给Dropdown加稳定的key属性(可选)
给Dropdown组件加固定的key属性,避免SPFX重渲染时把组件卸载再重建导致的状态丢失:
<Dropdown key="company-dropdown-fixed" placeholder="Select a company" label="Company" selectedKey={this.state.companyDropDownSelected} id="companyDdl" styles={dropdownStyles} options={this.props.companyOptions} onChange={this.onCompanyChange} />
内容的提问来源于stack exchange,提问作者Jason Eades
相关产品推荐
相关产品推荐

