为什么没有填充 Formik `touched` 属性?

问题描述 投票:0回答:3

我正在使用 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)
始终显示空对象。

reactjs react-bootstrap formik
3个回答
60
投票

@djheru 您的解决方案是正确的,因为 Formik 在

touched
事件而不是
blur
上设置
change
标志。 这里是 Formik 作者对此的评论: 您必须致电 Formiks
handleBlur
来通知 Formik
blur
事件已被触发 - 所以是的,需要这些处理程序。


44
投票

我通过访问在

handleBlur
函数参数中传递的
render
函数并将其添加为每个表单元素的
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>

0
投票

我的案例是

number().optional()
领域。 Formik 在处理
undefined
值时遇到问题。

切换到

number().required().nullable()
null
对我来说很方便:

// ❌ BAD
<input
  type="number"
  value={someOptionalNumber}
  onChange={({ target }) => setValue(target.valueAsNumber || undefined)}
/>


// ✅ GOOD
<input
  type="number"
  value={value ?? ""} // prevent "should not be null" error
  onChange={({ target }) => setValue(target.valueAsNumber || null)}
/>
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.