如何在TypeScript中集成react-hook-form、react-select与yup?
react-hook-form + react-select + yup 集成使用方案
前置依赖安装
先安装所需的三个核心库及适配工具:
npm install react-hook-form @hookform/resolvers yup react-select # 若使用TypeScript,可额外安装类型定义 npm install @types/react-select -D
集成核心逻辑
三者集成的核心是两点:
- 用react-hook-form提供的
Controller组件适配react-select的受控组件逻辑,完成双向绑定 - 用
@hookform/resolvers提供的yupResolver,将yup的校验规则注入到react-hook-form的校验生命周期中
完整使用示例
import { useForm, Controller } from 'react-hook-form'; import { yupResolver } from '@hookform/resolvers/yup'; import * as yup from 'yup'; import Select from 'react-select'; // 1. 定义yup校验规则 const schema = yup.object({ // 单选场景校验规则 singleSelect: yup.object().shape({ label: yup.string(), value: yup.string() }).required('请选择选项'), // 多选场景校验规则 multiSelect: yup.array().of( yup.object().shape({ label: yup.string(), value: yup.string() }) ).min(1, '至少选择1个选项').max(3, '最多选择3个选项') }); // 2. 模拟select选项数据 const options = [ { value: 'option1', label: '选项1' }, { value: 'option2', label: '选项2' }, { value: 'option3', label: '选项3' }, { value: 'option4', label: '选项4' } ]; function App() { // 3. 初始化react-hook-form,绑定yup校验器 const { control, handleSubmit, formState: { errors } } = useForm({ resolver: yupResolver(schema), defaultValues: { singleSelect: null, multiSelect: [] } }); const onSubmit = (data) => { console.log('提交的数据:', data); }; return ( <form onSubmit={handleSubmit(onSubmit)} style={{ maxWidth: 500, margin: '20px auto' }}> {/* 4. 绑定单选react-select */} <div style={{ marginBottom: 20 }}> <label>单选选择器</label> <Controller name="singleSelect" control={control} render={({ field }) => ( <Select {...field} options={options} placeholder="请选择选项" /> )} /> {/* 输出校验错误提示 */} {errors.singleSelect && <p style={{ color: 'red', margin: '5px 0 0 0' }}>{errors.singleSelect.message}</p>} </div> {/* 5. 绑定多选react-select */} <div style={{ marginBottom: 20 }}> <label>多选选择器</label> <Controller name="multiSelect" control={control} render={({ field }) => ( <Select {...field} isMulti options={options} placeholder="请选择最多3个选项" /> )} /> {errors.multiSelect && <p style={{ color: 'red', margin: '5px 0 0 0' }}>{errors.multiSelect.message}</p>} </div> <button type="submit" style={{ padding: '8px 16px' }}>提交</button> </form> ); } export default App;
常见注意事项
- 若你的select选项value不是
{label, value}的标准格式,需要在yup校验规则里对应修改字段结构定义,避免校验不生效 - 若需要实时校验,可在
useForm初始化时添加mode: 'onChange'配置,选择内容变化时立刻触发yup校验 - 提交时获取到的字段值和react-select返回的value格式完全一致,不需要额外做格式转换
内容的提问来源于stack exchange,提问作者Ace
相关产品推荐
相关产品推荐

