如何在 `react-hook-form` 库中将 Yup 验证模式与 Controller 组件一起使用
How to use Yup validation schema with the Controller component in `react-hook-form` lib
- 我们有一个想要使用的第 3 方组件
SecondaryInput
- 想使用
Yup
验证(不知道如何在 Controller
组件中将 yup 与规则道具一起使用)
- 受控组件在子组件内部,所以我使用的是
useFormContext
- 架构代码不工作
我的代码是这样的
注意:我不能在自定义组件中使用 ref,因为它不使用像 ref
这样的道具
父组件
const schema = yup.object().shape({
patientIdentity: yup.object().shape({
firstName: yup.string().required('Required field'),
lastName: yup.string().required('Required field'),
}),
});
const methods = useForm();
const {
errors,
handleSubmit,
register,
setValue,
reset,
getValues,
} = useForm({
defaultValues: {
patientIdentity: {
firstName: 'test 1',
lastName: 'Test 2',
},
},
validationSchema: schema,
});
const onSubmit = (data, e) => {
console.log('onSubmit');
console.log(data, e);
};
const onError = (errors, e) => {
console.log('onError');
console.log(errors, e);
};
console.log('errors', errors); // Not able to see any any error
console.log('getValues:> ', getValues()); Not able to see any any values
return (
<View style={[t.flex1]}>
{/* Removed code from here */}
<View style={[t.flex1, t.selfCenter]}>
<FormProvider {...methods}>
<View style={[t.flexCol]}>
<PatientForm /> // <<Child component
<PrimaryButton
style={[t.pL3, t.h10]}
onPress={handleSubmit(onSubmit, onError)}
>
Save changes
</PrimaryButton>
</View>
</FormProvider>
</Row>
</View>
子组件
const {
control,
register,
getValues,
setValue,
errors,
defaultValuesRef,
} = useFormContext();
console.log('errors:>>', errors); // NOt able to log
console.log('Identity | getValues>', getValues());
return (
<DetailCard title="Identity">
<Controller
control={control}
render={(props) => {
const { onChange, onBlur, value } = props;
return (
<SecondaryInput
label="Legal First Name"
value={value}
onTextChange={(value) => onChange(value)}
onBlur={onBlur}
/>
);
}}
name="patientIdentity.firstName"
rule={register({
required: ' name cannot be empty',
})}
defaultValue=""
/>
<Controller
control={control}
as={({ onChange, onBlur, value }) => {
return (
<SecondaryInput
label="Legal Last Name"
value={value}
onTextChange={(value) => onChange(value)}
onBlur={onBlur}
/>
);
}}
name="patientIdentity.lastName"
rules={{
required: 'this is required field',
message: 'required field',
}}
defaultValue=""
/>
</DetailCard>
)
您需要检查几件事:
schema
对象不依赖于任何 local-scoped 变量。您可以将它放在函数之外,这样组件就不会在每次渲染时都重新创建它
首先将是的 schema
对象传递给 yupResolver
,而不是直接传递给 resolver
import React from 'react';
import { useForm } from 'react-hook-form';
import { yupResolver } from '@hookform/resolvers/yup';
import * as yup from "yup";
const schema = yup.object().shape({
patientIdentity: yup.object().shape({
firstName: yup.string().required('Required field'),
lastName: yup.string().required('Required field'),
}),
});
const App = () => {
const { ... } = useForm({
resolver: yupResolver(schema),
});
return (...);
};
- 如果您使用 third-party 库编写验证规则,例如
Yup
,您可以从 Controller
中删除 rules
道具,因为它们是重复的。
- 我们有一个想要使用的第 3 方组件
SecondaryInput
- 想使用
Yup
验证(不知道如何在Controller
组件中将 yup 与规则道具一起使用) - 受控组件在子组件内部,所以我使用的是
useFormContext
- 架构代码不工作
我的代码是这样的
注意:我不能在自定义组件中使用 ref,因为它不使用像 ref
父组件
const schema = yup.object().shape({
patientIdentity: yup.object().shape({
firstName: yup.string().required('Required field'),
lastName: yup.string().required('Required field'),
}),
});
const methods = useForm();
const {
errors,
handleSubmit,
register,
setValue,
reset,
getValues,
} = useForm({
defaultValues: {
patientIdentity: {
firstName: 'test 1',
lastName: 'Test 2',
},
},
validationSchema: schema,
});
const onSubmit = (data, e) => {
console.log('onSubmit');
console.log(data, e);
};
const onError = (errors, e) => {
console.log('onError');
console.log(errors, e);
};
console.log('errors', errors); // Not able to see any any error
console.log('getValues:> ', getValues()); Not able to see any any values
return (
<View style={[t.flex1]}>
{/* Removed code from here */}
<View style={[t.flex1, t.selfCenter]}>
<FormProvider {...methods}>
<View style={[t.flexCol]}>
<PatientForm /> // <<Child component
<PrimaryButton
style={[t.pL3, t.h10]}
onPress={handleSubmit(onSubmit, onError)}
>
Save changes
</PrimaryButton>
</View>
</FormProvider>
</Row>
</View>
子组件
const {
control,
register,
getValues,
setValue,
errors,
defaultValuesRef,
} = useFormContext();
console.log('errors:>>', errors); // NOt able to log
console.log('Identity | getValues>', getValues());
return (
<DetailCard title="Identity">
<Controller
control={control}
render={(props) => {
const { onChange, onBlur, value } = props;
return (
<SecondaryInput
label="Legal First Name"
value={value}
onTextChange={(value) => onChange(value)}
onBlur={onBlur}
/>
);
}}
name="patientIdentity.firstName"
rule={register({
required: ' name cannot be empty',
})}
defaultValue=""
/>
<Controller
control={control}
as={({ onChange, onBlur, value }) => {
return (
<SecondaryInput
label="Legal Last Name"
value={value}
onTextChange={(value) => onChange(value)}
onBlur={onBlur}
/>
);
}}
name="patientIdentity.lastName"
rules={{
required: 'this is required field',
message: 'required field',
}}
defaultValue=""
/>
</DetailCard>
)
您需要检查几件事:
schema
对象不依赖于任何 local-scoped 变量。您可以将它放在函数之外,这样组件就不会在每次渲染时都重新创建它首先将是的
schema
对象传递给yupResolver
,而不是直接传递给resolver
import React from 'react';
import { useForm } from 'react-hook-form';
import { yupResolver } from '@hookform/resolvers/yup';
import * as yup from "yup";
const schema = yup.object().shape({
patientIdentity: yup.object().shape({
firstName: yup.string().required('Required field'),
lastName: yup.string().required('Required field'),
}),
});
const App = () => {
const { ... } = useForm({
resolver: yupResolver(schema),
});
return (...);
};
- 如果您使用 third-party 库编写验证规则,例如
Yup
,您可以从Controller
中删除rules
道具,因为它们是重复的。