React结合useForm读取API返回值填充react-select实现数据回显
react-select 结合 react-hook-form 异步赋值回显方案
问题原因
当前实现存在3个核心问题导致接口返回值无法在选择组件上正常展示:
CreatableSelect组件没有和Controller提供的表单字段状态做绑定,使用了外部自定义的value变量,无法感知setValue触发的表单状态更新- 自定义的
handleKeywordChange方法没有把变更后的值同步回react-hook-form的表单状态,造成双数据源不一致 useEffect依赖数组为空,若接口数据异步返回晚于组件首次渲染,赋值逻辑不会二次执行;同时setValue未加渲染触发配置,更新后不会驱动组件重渲染
具体修复代码
1. 修正useEffect赋值逻辑
给赋值逻辑加对依赖和配置项,保证异步数据返回后能正确触发视图更新:
useEffect(() => { if (createQuestion) { setValue("framework", createQuestion.framework); setValue("benchmark", createQuestion.benchmark); setValue("difficulty", createQuestion.difficulty); // 加配置项确保值更新后触发组件重渲染、校验状态同步 setValue("Keywords", createQuestion.Keywords, { shouldDirty: true, shouldValidate: true, shouldTouch: true }); setValue("isAnswerTrue", createQuestion.isAnswerTrue === "true" ? "true" : "false"); setValue("articleAnswer", createQuestion.articleAnswer?.answer); } }, [createQuestion, setValue]); // 把接口返回数据加入依赖,数据返回后自动执行赋值
2. 修正Controller和CreatableSelect的绑定逻辑
不要在render里用外部自定义的value和onChange,直接使用Controller注入的字段属性,自定义逻辑处理完后必须同步值给表单:
<Controller control={control} name="Keywords" rules={{ required: true }} render={({ field }) => ( <CreatableSelect components={components} inputValue={inputValue} isClearable isMulti menuIsOpen={false} onChange={(selectedVal) => { // 保留你原有关键词变更的自定义逻辑 handleKeywordChange(selectedVal); // 必须把选中值同步回react-hook-form状态 field.onChange(selectedVal); }} onInputChange={handleKeywordInputChange} onKeyDown={handleKeyDown} placeholder="Enter Keywords" // 直接使用表单状态里的值,删除外部自定义的value状态避免冲突 value={field.value} className="react-select-container" classNamePrefix="react-select" styles={colorStyles} /> )} />
注意事项
- 如果你之前单独用
useState维护了Keywords的选中值,直接删除即可,所有选中状态统一交给react-hook-form管理,避免双数据源不同步 - 你当前接口返回的Keywords数组项已经带了
value和label字段,完全符合react-select的数据格式要求,不需要额外做格式转换 - 如果你的
handleKeyDown里有回车新增关键词的逻辑,新增完关键词后也要调用field.onChange把新的关键词数组同步给表单
内容的提问来源于stack exchange,提问作者Ahmed Radi
相关产品推荐
相关产品推荐

