react-hook-form结合formlist使用
一.网站
react-hook-form=>react-hook-form.nodejs.cn/get-started yup=>github.com/jquense/yup…
二.基础使用
1) name命名规则 根据index定位
name={`id`}
name={`tabList.${index}.infUrl`}
name={`tabList.${index}.header.${headerIndex}.infUrl`}
2) 多个list 重命名
const { fields:tabListFields, append:tabListAppend, remove:tabListRemove } = useFieldArray({
control,
name: "tabList",
});
const { fields:tabFields, append:tabAppend, remove:tabRemove } = useFieldArray({
control,
name: "tab",
});
3) 校验
- 1.可以使用handleSubmit自动校验
const onClick = (values:any) = > {} //values 校验后的表单值
<Button onClick={handleSubmit(onClick)} />
<Button onClick={handleSubmit(()=>onClick(1))} />//传参格式
- 2.使用trigger手动校验
const isValid = await trigger()
if(!isValid) return
- 3.formlist校验只能和yup结合使用
4) 指令
- trigger校验
- watch监听
//不用额外处理,watch后动态值使用getValues()['id']获取即可
watch('id')
watch(['id','name'])
watch('tabList',['id','name']) //formlist
5) 踩坑
- 使用fileds进行渲染时,key必须使用field.id,否则获取不到值
{fields?.map((field:any,index:number)=>(<div key={field.id}></div>)}
二.使用yup
- list中嵌套数组
// tabList = [{id:'',header:[{...}]}]
const validationSchema = yup.object({
tabList: yup.array().of(
yup.object().shape({
id: yup.string().required("请选择"),
// Header 校验
header: yup.array().of(
yup.object().shape({
key: yup.string().required("请输入参数名"),
value: yup.string().required("请输入参数值"),
})
),
})
),
});
- 自定义校验规则 动态校验
// 更多查询yup官网
const validationSchema = yup.object({
tabList: yup.array().of(
yup.object().shape({
// react6只允许函数校验
id: yup.string().when("type", ([type], schema) => {
// type 参数name
return type == "1"
? schema.required("请选择规则类型")
: schema.notRequired();
}),,
})
),
});
三.示例代码
import * as yup from "yup";
import { yupResolver } from "@hookform/resolvers/yup";
/** yup校验formlist */
const validationSchema = yup.object({
tabList: yup.array().of(
yup.object().shape({
id: yup.string().required("请选择id"),
})
),
});
const { control, formState:{errors}, reset, setValue, getValues, watch, trigger } =
useForm<any>({
defaultValues: {
tabList:[]
},
resolver: yupResolver(validationSchema),
});
<div>
{fields?.map((field:any,index:number)=>(
<>
<Controller
name={`tabList.${index}.id`}
control={control}
rules={{ required: '请输入' }} //非formlist校验
render={({field}=>(
<TextField {...field} />
))}
/>
{errors[index]?.id&&(<FormHelperText error>
{errors[itemIndex]?.id.message as string}
</FormHelperText>)}
</>
)
}
</div>