Как использовать схему проверки Yup с компонентом контроллера в библиотеке `react-hook-form`

#reactjs #forms #react-native #yup #react-hook-form

#reactjs #формы #react-native #да #react-hook-form

Вопрос:

  • У нас есть сторонний компонент, который мы хотим использовать SecondaryInput
  • Хотите использовать Yup проверку (не знаю, как использовать yup с реквизитами правил в Controller компоненте)
  • Контролируемый компонент находится внутри дочернего компонента, поэтому я использую useFormContext
  • Код схемы не работает

Мой код выглядит примерно так

ПРИМЕЧАНИЕ: я не могу использовать ссылку внутри пользовательского компонента, поскольку он не принимает реквизитов, таких как 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>
)
  

Ответ №1:

Есть несколько вещей, которые вам нужно проверить:

  • schema Объект не зависит ни от каких переменных локальной области. Вы можете поместить его вне функции, чтобы компонент не воссоздавал его при каждом рендеринге

  • Передайте объект yup 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 (...);
};
  
  • Если вы пишете правила проверки, используя стороннюю библиотеку, например Yup , вы можете удалить rules реквизиты из Controller , поскольку они дублируются.

Комментарии:

1. Просто добавляю ссылку здесь, чтобы другие могли помочь: github.com/react-hook-form/resolvers

2. У меня все еще не работает.