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

ReactJS编辑Survey表单时Select下拉选择器偶发无法正常选中赋值问题

问题根因
    1. 竞态条件:拉取survey详情、拉取元数据两个异步请求返回顺序不固定,_setProperValForMetaDataSelect方法执行时经常出现其中一类数据未加载完成的情况,导致匹配不到对应值
    1. 入口判断逻辑完全失效:this.state.surveyMeta是对象,不存在length属性,原判断this.state.surveyMeta.length == 0永远为false,无法拦截数据未加载完成的执行场景
    1. 值匹配逻辑写反:元数据结构为{数字key: 文本value},需求是根据接口返回的文本值找对应数字key,但代码中判断条件写为if (key == survey_type),导致大部分场景匹配不到值,返回空字符串覆盖原有值
    1. Select组件属性错误:Formik是受控组件模式,代码中用了只在首次渲染生效的defaultValue,后续state更新后Select不会跟着响应,就会显示默认的--select--
修复方案

1. 修正转换方法的入口判断与匹配逻辑

_setProperValForMetaDataSelect() {
    // 必须同时满足survey加载完成、元数据加载完成才执行转换
    if (this.props.isSurveyLoading || this.state.surveyMeta.survey_types.length === 0) {
        return
    }

    const { survey_types, survey_subtypes, transit_types, currencies, live_survey_types } = this.state.surveyMeta
    const { currency, survey_type, survey_subtype, transit_type, live_survey_type } = this.state.survey || {}

    let _currency = ''
    let _survey_type = ''
    let _survey_subtype = ''
    let _transit_type = ''
    let _live_survey_type = ''

    // 修正匹配逻辑:用返回的文本值匹配元数据的value,取对应数字key
    currencies.forEach((item) => {
        for (const [key, value] of Object.entries(item)) {
            if (value == currency) {
                _currency = key
            }
        }
    })

    survey_types.forEach((item) => {
        for (const [key, value] of Object.entries(item)) {
            if (value == survey_type) {
                _survey_type = key
            }
        }
    })

    transit_types.forEach((item) => {
        for (const [key, value] of Object.entries(item)) {
            if (value == transit_type) {
                _transit_type = key
            }
        }
    })

    survey_subtypes.forEach((item) => {
        for (const [key, value] of Object.entries(item)) {
            if (value == survey_subtype) {
                _survey_subtype = key
            }
        }
    })

    live_survey_types.forEach((item) => {
        for (const [key, value] of Object.entries(item)) {
            if (value == live_survey_type) {
                _live_survey_type = key
            }
        }
    })

    let updatedValues = {
        currency: _currency || currency,
        survey_type: _survey_type || survey_type,
        survey_subtype: _survey_subtype || survey_subtype,
        transit_type: _transit_type || transit_type,
        live_survey_type: _live_survey_type || live_survey_type
    }
    
    this.setState({
        survey: {
            ...this.state.survey,
            ...updatedValues
        }
    })
}

2. 修正Select组件属性,适配受控模式

把_generateSelectElement方法中的defaultValue替换为value,绑定Formik的对应字段值:

_generateSelectElement(name, onChange, onBlur, options, selectedValue = null) {
    return <Input
        name={name}
        type='select'
        onBlur={onBlur}
        onChange={onChange}
        value={selectedValue || ''} // 替换原defaultValue
    >
        <option value="">--Select--</option>
        {options ? options.map((item) => {
            for (const [key, value] of Object.entries(item)) {
                return <option key={value} value={key}>{value}</option> // 同时修正value和显示文本的对应关系
            }
        }) : null}
    </Input>
}

3. 优化异步加载逻辑避免竞态

可以新增两个状态标记isMetaLoaded和isSurveyLoaded,只有两个标记都为true的时候才调用一次_setProperValForMetaDataSelect,避免多次无效调用覆盖正确值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.09 19:39:03