如何让react-hook-form配合chakra-react-select保存值数组而非选项对象数组
问题
使用 chakra-react-select(适配 Chakra UI 的 react-select 封装)搭配 react-hook-form 开发时,已通过以下代码关联组件与表单:
<Controller control={control} name={name} rules={validation} render={({ field }) => { const Component = isCreatable ? CreatableSelect : Select; return ( <Component isRequired={Boolean(validation?.required)} isClearable={isClearable} isDisabled={isDisabled} isLoading={isLoading} isMulti={isMulti} isSearchable={isSearchable} options={options} {...field} /> ); }} />
功能正常,但表单保存的数据不符合预期:期望得到值数组如 ['value1', 'value2', ...],实际得到选项对象数组如 [{ label: 'Value 1', value: 'value1' }, ...]。由于 yup 验证在提交前执行,无法在提交阶段处理数据转换,求最简洁的修改方式。
解决方案
最简洁的方式是在 Controller 内部处理值的双向转换:将组件输出的选项对象数组转成值数组存入表单,同时将表单的 value 数组转成组件需要的选项对象数组用于回显。
修改后的代码如下:
<Controller control={control} name={name} rules={validation} render={({ field: { onChange, value, ...restField } }) => { const Component = isCreatable ? CreatableSelect : Select; // 把表单的value数组转成组件需要的选项对象数组(支持单选/多选) const selectValue = isMulti ? options.filter(opt => value?.includes(opt.value)) : options.find(opt => opt.value === value); // 把组件选中的选项转成纯值数组/单个值传给表单 const handleChange = (selectedOptions) => { const newValue = isMulti ? selectedOptions?.map(opt => opt.value) || [] : selectedOptions?.value || null; onChange(newValue); }; return ( <Component isRequired={Boolean(validation?.required)} isClearable={isClearable} isDisabled={isDisabled} isLoading={isLoading} isMulti={isMulti} isSearchable={isSearchable} options={options} value={selectValue} onChange={handleChange} {...restField} /> ); }} />
关键逻辑说明
- 值回显处理:
selectValue根据是否多选,从options中筛选出与表单 value 匹配的选项对象,确保组件能正确显示选中状态。 - 值提交处理:
handleChange拦截组件的 onChange 事件,提取选中选项的value属性,转成纯值数组/单个值后再传给 react-hook-form 的onChange,保证表单存储的是预期格式。 - 保留原组件的所有其他属性,不影响原有功能。
内容的提问来源于stack exchange,提问作者Barry Michael Doyle
相关产品推荐
相关产品推荐

