如何将 Yup 验证模式与"反应钩子形式"库中的控制器组件一起使用


  • 我们有一个想要使用的第三方组件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对象不依赖于任何局部范围的变量。您可以将其放在函数外部,这样组件就不会在每次呈现时重新创建它

  • 首先将 yupschema对象传递给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 (...);
};
  • 如果您使用第三方库(如Yup)编写验证规则,则可以从Controller中删除rulesprops,因为它们是重复的。

最新更新