为什么Formik的“touched”属性没有被填充?

42

我在使用React、Formik、react-bootstrap和yup进行表单制作。我尝试显示验证错误,但是touched属性没有填充字段。

const schema = yup.object({
  name: yup.string().required(),
  email: yup
    .string()
    .email()
    .required(),
});

const ChildForm = props => {
  const { child: { name = '', email = '' } = {} } = props;
  const submitHandler = ({name, email}) => console.log(name, email);

  return (
    <Formik
      validationSchema={schema}
      onSubmit={submitHandler}
      initialValues={{ name, email }}
      render={({ handleSubmit, handleChange, values, touched, errors }) => 
      {
        console.log('touched: ', touched);
        return (
          <Form noValidate className="mt-4" onSubmit={handleSubmit}>
            <Form.Row>
              <Form.Group as={Col} controlId="name">
                <Form.Label>Full Name</Form.Label>
                <Form.Control
                  name="name"
                  required
                  value={values.name}
                  onChange={handleChange}
                  isValid={touched.name && !errors.name}
                  isInvalid={touched.name && errors.name}
                  type="text"
                  placeholder="Your child's name"
                />
                <Form.Control.Feedback>Looks good!</Form.Control.Feedback>
                <Form.Control.Feedback type="invalid">
                  {errors.name || 'Please enter your child\'s name'}
                </Form.Control.Feedback>
              </Form.Group>
            </Form.Row>
            <Form.Row>
              <Form.Group as={Col} controlId="email">
                <Form.Label>Email Address</Form.Label>
                <Form.Control
                  name="email"
                  required
                  value={values.email}
                  onChange={handleChange}
                  isValid={touched.email && !errors.email}
                  isInvalid={touched.email && errors.email}
                  type="text"
                  placeholder="Your child's email address"
                />
                <Form.Control.Feedback>
                  No spam, we promise!
                </Form.Control.Feedback>
                <Form.Control.Feedback type="invalid">
                  {errors.email || 'Please enter a valid email address'}
                </Form.Control.Feedback>
              </Form.Group>
            </Form.Row>
            <Form.Row className="float-right">
              <Button variant="success" onClick={handleSubmit}>
                <Icon icon={faSave} />
                &nbsp; Submit
              </Button>
            </Form.Row>
          </Form>
        );
      }}
    />
  );
}

我在这里做错了什么?console.log(touched) 总是显示一个空对象。

2个回答

53

@djheru,您的解决方案是正确的,因为Formik在blur事件上设置标志而不是在change事件上设置。这里是关于这个问题的Formik作者评论:链接 您必须调用Formiks handleBlur来通知Formik已经触发了blur事件 - 所以是的,这些处理程序是必需的。


41
我通过访问传递给“render”函数参数的“handleBlur”函数并将其添加为每个表单元素的“onBlur”处理程序,使其工作。不确定是否需要这样做,因为我正在使用 react-bootstrap 表单组件,但是 react-bootstrap 文档中有一个 Formik 示例,但“touched”对象没有被更新。
(
    <Formik
      validationSchema={schema}
      onSubmit={submitForm}
      initialValues={{ name, email }}
      render={({
        handleSubmit,
        handleChange,
        handleBlur, // handler for onBlur event of form elements
        values,
        touched,
        errors,
      }) => {
        return (
          <Form noValidate className="mt-4" onSubmit={handleSubmit}>
            <Form.Row>
              <Form.Group as={Col} controlId="nameControl">
                <Form.Label>Full Name</Form.Label>
                <Form.Control
                  name="name"
                  required
                  value={values.name}
                  onChange={handleChange}
                  onBlur={handleBlur} // This apparently updates `touched`?
                  isValid={touched.name && !errors.name}
                  isInvalid={touched.name && errors.name}
                  type="text"
                  placeholder="Your child's name"
                />
                <Form.Control.Feedback>Looks good!</Form.Control.Feedback>
                <Form.Control.Feedback type="invalid">
                  {errors.name || 'Please enter your child\'s name'}
                </Form.Control.Feedback>
              </Form.Group>
            </Form.Row>

3
你帮我省了不少麻烦!你能相信吗,官方的Bootstrap-React教程关于如何使用Formik验证表单的部分是错误的,并且缺少这个细节!https://react-bootstrap.github.io/components/forms/#forms-validation-libraries - gene b.
感谢您提供的代码示例。这使得这个答案超过了被选中的答案。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接