You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中AutoComplete组件获取最终输入值的正确方式及状态错误排查

React Autocomplete组件"Cannot update during state transition"错误解决

问题背景

你在使用React Autocomplete组件时触发了Cannot update during state transition错误,排查后发现问题出在renderInput的实现代码里。原本想在renderInput中读取输入值,通过修改alleenUnCodes状态来过滤选项,但这个阶段属于组件渲染流程,此时调用setState会打断状态过渡,导致错误。同时你希望仅在用户真正选中选项时(比如点击弹窗选项、选中高亮选项按回车)执行对应方法。

原问题代码:

public render() {
  const { classes } = this.props;

  return (
    <div className={classes.autoSuggest}>
      <Autocomplete
        ListboxProps={{ style: { maxHeight: 200, overflow: 'auto' } }}
        autoHighlight={true}
        disablePortal={false}
        options={this.getOptions()}
        onClick={(_event, value) => this.onSelect(value)}
        renderInput={(input) => { return this.onInput(input);}}
      />
    </div>
  );
}

private onInput(input: AutocompleteRenderInputParams) {
  if (!this.state.alleenUnCodes &&
      input.inputProps.value !== undefined &&
      input.inputProps.value.toString() !== "" &&
      input.inputProps.value.toString().charAt(0) === '/') {
    this.setState({alleenUnCodes: true});
  }

  if (this.state.alleenUnCodes &&
      input.inputProps.value !== undefined &&
      input.inputProps.value.toString().charAt(0) !== '/') {
    this.setState({alleenUnCodes: false});
  }

  return <TextField {...input} label={'Type GEVI/UN of /UN code (bv 20/1002, of /20)'}/>;
}

错误原因

renderInput是Autocomplete组件渲染流程的一部分,在这个阶段调用setState会触发额外的重新渲染,违反React的状态更新时机规则,因此抛出Cannot update during state transition错误。

解决方法

不需要在renderInput里通过修改状态来过滤选项,Autocomplete组件本身提供了filterOptions参数,可以直接用它实现自定义过滤逻辑;同时通过onChange(或组件的onSelect)处理用户选中选项的操作,确保仅在用户确认选中时执行对应方法。

修改后的代码示例:

public render() {
  const { classes } = this.props;

  return (
    <div className={classes.autoSuggest}>
      <Autocomplete
        ListboxProps={{ style: { maxHeight: 200, overflow: 'auto' } }}
        autoHighlight={true}
        disablePortal={false}
        options={this.getOptions()}
        // 用户选中选项时执行逻辑
        onChange={(_event, value) => this.onSelect(value)}
        // 自定义选项过滤逻辑
        filterOptions={(options, state) => {
          const inputValue = state.inputValue || '';
          // 根据输入值开头是否为'/'来过滤选项
          if (inputValue.startsWith('/')) {
            // 替换成你的UN code过滤逻辑
            return options.filter(option => option.includes('UN'));
          } else {
            // 替换成你的GEVI/UN过滤逻辑
            return options.filter(option => option.includes('GEVI') || option.includes('UN'));
          }
        }}
        renderInput={(input) => (
          <TextField {...input} label={'Type GEVI/UN of /UN code (bv 20/1002, of /20)'}/>
        )}
      />
    </div>
  );
}

private onSelect(value: /* 替换成你的选项类型 */) {
  // 真正选中值时执行的业务逻辑
}

关键调整说明

  • 移除了renderInput中调用setState的逻辑,避免在渲染阶段修改状态触发错误
  • 使用filterOptions直接根据输入值动态过滤选项,无需维护额外的alleenUnCodes状态
  • 通过onChange处理用户选中选项的操作,确保只有在用户确认选中(点击选项、按回车选中高亮项)时才执行对应逻辑

内容的提问来源于stack exchange,提问作者JasperMW

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 21:05:20