Ошибка типа: схема [syn c? 'validateSyn c': 'validate'] не является функцией - PullRequest
1 голос
/ 07 апреля 2020

Я пытаюсь проверить форму пользовательского интерфейса, используя Formik и Yup, но получаю ошибку.

Это моя схема, которую я импортирую из другого файла.

export const schema = Yup.object({
  email: Yup.string()
    .email('Invalid Email')
    .required('This Field is Required'),
});

Это где я использую проверку. Если я напишу validation = schema, это не даст ошибки, но проверки также не будет. Если я изменю его на {schema}, приложение вылетает.

export default function RemoveUserPage() {
  const [isSubmitted, setIsSubmitted] = useState(false);
  const [isRemoved, setIsRemoved] = useState(false);
  const [errorMessage, setErrorMessage] = useState('');

  const [removeUser] = useMutation(REMOVE_USER);

  let submitForm = (email: string) => {
    setIsSubmitted(true);
    removeUser({
      variables: {
        email: email,
      },
    })      
  };

  const formik = useFormik({
    initialValues:{ email: '' },
    onSubmit:(values, actions) => {
       setTimeout(() => {
          alert(JSON.stringify(values, null, 2));
          actions.setSubmitting(false);
          }, 1000);
        },
       validationSchema:{schema}
    })

    const handleChange = (e: ChangeEvent<HTMLInputElement>)=>{
      const {name,value} = e.target;
      formik.setFieldValue(name,value);
     }

  return (
    <div>
              <Form
                onSubmit={e => {
                  e.preventDefault();
                  submitForm(formik.values.email);
                }}>
                <div>
                  <TextField
                    variant="outlined"
                    margin="normal"
                    id="email"
                    name="email"
                    helperText={formik.touched.email ? formik.errors.email : ''}
                    error={formik.touched.email && Boolean(formik.errors.email)}
                    label="Email"
                    value={formik.values.email}
                    //onChange={change.bind(null, 'email')}
                    onChange={formik.handleChange}
                  />
                  <br></br>
                  <CustomButton
                    disabled={!formik.values.email}
                    text={'Remove User'}
                  />
                </div>
              </Form>
    </div>
  );
}

Кроме того, я также хочу передать условие isValid! в disabled кнопки, но я не могу понять, как это сделать. Я получил его, так как мог написать его в подпорках, но не уверен, как его использовать в useFormik ().

Кроме того, когда я отправляю форму, текстовые поля не сбрасываются автоматически. Как я могу это исправить?

Ошибка:

TypeError: schema[sync ? 'validateSync' : 'validate'] is not a function. (In 'schema[sync ? 'validateSync' : 'validate'](validateData, {
    abortEarly: false,
    context: context
  })', 'schema[sync ? 'validateSync' : 'validate']' is undefined)

Раньше я использовал <Formik>. В этом случае проверка была выполнена, когда я печатал, например, если я напишу 'hfs', он немедленно сообщит мне недействительный адрес электронной почты, пока я печатаю. Тем не менее, с помощью useFormik (a cc к ответу ниже), он сообщает неверный адрес электронной почты только после того, как я отправлю форму. Я не хочу, чтобы это произошло, потому что после отправки формы вызывается и мутация. Я хочу сохранить валидацию отдельно. Это то, что я использовал ранее

export default function RemoveUserPage() {
  const [isSubmitted, setIsSubmitted] = useState(false);
  const [isRemoved, setIsRemoved] = useState(false);
  const [errorMessage, setErrorMessage] = useState('');

  const [removeUser] = useMutation<DeleteUserResponse>(REMOVE_USER);

  let submitForm = (email: string) => {
    setIsSubmitted(true);
    removeUser({
      variables: {
        email: email,
      },
    })
      .then(({ data }: ExecutionResult<DeleteUserResponse>) => {
        if (data !== null && data !== undefined) {
          setIsRemoved(true);
        }
      })
  };

  return (
    <div>
      <Formik
        initialValues={{ email: '' }}
        onSubmit={(values, actions) => {
          setTimeout(() => {
            alert(JSON.stringify(values, null, 2));
            actions.setSubmitting(false);
          }, 1000);
        }}
        validationSchema={schema}>
        {props => {
          const {
            values: { email },
            errors,
            touched,
            handleChange,
            isValid,
            setFieldTouched,
          } = props;
          const change = (name: string, e: FormEvent) => {
            e.persist();
            handleChange(e);
            setFieldTouched(name, true, false);
          };
          return (
            <Wrapper>
              <Form
                onSubmit={e => {
                  e.preventDefault();
                  submitForm(email);
                }}>
                <div>
                  <TextField
                    variant="outlined"
                    margin="normal"
                    id="email"
                    name="email"
                    helperText={touched.email ? errors.email : ''}
                    error={touched.email && Boolean(errors.email)}
                    label="Email"
                    value={email}
                    onChange={change.bind(null, 'email')}
                  />
                  <br></br>
                  <CustomButton
                    disabled={!isValid || !email}
                    text={'Remove User'}
                  />
                </div>
              </Form>
          );
        }}
      </Formik>
    </div>
  );
}

1 Ответ

5 голосов
/ 07 апреля 2020

Это должна быть validationSchema: схема вместо {schema}

Причина, по которой он не проверяется, заключается в том, что вы не используете handleSubmit от formik

useFormik({
initialValues:{ email: '' },
onSubmit:(values, actions) => {
   setTimeout(() => {
      alert(JSON.stringify(values, null, 2));
      actions.setSubmitting(false);
      }, 1000);
    },
   validationSchema: schema
})

...

<Form onSubmit={formik.handleSubmit}>
  ...
  <CustomButton
       disabled={formik.touched.email && formik.errors.email ? true : false}
       text={'Remove User'}
  />
  ...
</Form>

Он должен использовать formik's handleSubmit для получения проверки того, что вы определяете для validationSchema

Также передайте форму formik.touched.email && formik.errors.email отключенной команде кнопки.

На основании вашего запроса, чтобы подтвердить поле при вводе вы должны сделать следующим образом:

<TextField
        variant="outlined"
        margin="normal"
        id="email"
        name="email"
        helperText={formik.touched.email ? formik.errors.email : ""}
        error={formik.touched.email && Boolean(formik.errors.email)}
        label="Email"
        value={formik.values.email}
        onChange={props => {
          formik.handleChange(props);
          formik.handleBlur(props);
        }}
        onBlur={formik.handleBlur}
      />
...