You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React+Formik注册表单Submit按钮点击无法提交问题修复

Formik注册表单提交无响应修复方案

核心问题根因

  • 所有表单输入控件未接入Formik状态管理:自定义的FormikControl仅渲染原生input,没有绑定Formik的字段状态,用户输入内容不会同步到Formik的values对象,必填字段始终为空,校验永远不通过
  • 提交按钮禁用逻辑缺陷:按钮绑定了disabled={!formik.isValid},由于初始状态下表单校验未触发+字段值未同步,按钮始终处于禁用状态,点击自然无法触发提交
  • 单选框实现完全错误:手写的原生radio没有绑定name="modeOfContact"属性,value值也和校验规则要求的emailmoc/telephonemoc不匹配,Formik无法获取该必填字段的值
  • 多处拼写错误:options配置项里的vlaue为拼写错误,FormikContainer里的校验属性validationschema不符合Formik要求的驼峰命名validationSchema
  • 校验规则写法错误:confirmPassword的oneOf校验把空字符串放进了匹配数组,会导致两次密码不一致也能通过校验

分步修复代码

1. 重构FormikControl组件,接入Formik字段绑定

修改FormikControl.js,用Formik内置的Field组件替换原生input,新增radio类型控件支持:

import React from 'react';
import { Field } from 'formik';

function FormikControl({ control, id, label, name, options, ...rest }) {
  return (
    <>
      {control === 'input' && (
        <>
          <label htmlFor={id || name}>{label}</label>
          <Field id={id || name} name={name} {...rest} />
        </>
      )}
      {control === 'radio' && (
        <div style={{margin: '12px 0'}}>
          <label style={{fontWeight: 'bold', display: 'block', marginBottom: '8px'}}>{label}</label>
          {options.map(opt => (
            <label key={opt.value} style={{marginRight: '20px', fontWeight: 'normal'}}>
              <Field type="radio" name={name} value={opt.value} style={{marginRight: '6px'}} />
              {opt.key}
            </label>
          ))}
        </div>
      )}
    </>
  );
}

export default FormikControl;

2. 修正RegistrationForm.js的错误

替换原生radio控件、修正拼写错误、调整校验规则和按钮禁用逻辑:

import React from 'react';
import { Formik, Form } from 'formik';
import * as yup from 'yup';
import FormikControl from './FormikControl';
import classes from './Registration.module.css';

function Registrationform() {
  // 修正value拼写错误
  const options = [
    { key: 'Email', value: 'emailmoc' },
    { key: 'Telephone', value: 'telephonemoc' }
  ];

  const initialValues = {
    email: '',
    password: '',
    confirmPassword: '',
    modeOfContact: '',
    phone: ''
  };

  const validationSchema = yup.object({
    email: yup.string().email('Invalid email format').required('Required'),
    password: yup.string().required('Required'),
    // 修正oneOf参数,移除数组内的空字符串
    confirmPassword: yup
      .string()
      .oneOf([yup.ref('password')], 'Passwords must match')
      .required('required'),
    modeOfContact: yup.string().required('Required'),
    phone: yup.string().when('modeOfContact', {
      is: 'telephonemoc',
      then: yup.string().required('Required')
    })
  });

  const onSubmit = (values) => {
    console.log('Form data', values);
  };

  return (
    <div>
      <h1>Registration</h1>

      <Formik
        initialValues={initialValues}
        validationSchema={validationSchema}
        onSubmit={onSubmit}
        validateOnMount={true}
      >
        {(formik) => {
          return (
            <Form className={classes.Registrationform}>
              <FormikControl
                control="input"
                type="email"
                label="Email"
                name="email"
              />

              <FormikControl
                control="input"
                type="password"
                label="Password"
                name="password"
              />

              <FormikControl
                control="input"
                type="password"
                label="Confirm Password"
                name="confirmPassword"
              />

              <FormikControl
                control="input"
                type="text"
                label="Phone number"
                name="phone"
              />

              {/* 替换手写radio为封装的控件 */}
              <FormikControl
                control="radio"
                label="Mode of Contact"
                name="modeOfContact"
                options={options}
              />

              {/* 修正禁用逻辑:表单已修改且校验通过时才可点击 */}
              <button type="submit" disabled={!(formik.dirty && formik.isValid)}>
                Submit
              </button>
            </Form>
          );
        }}
      </Formik>
    </div>
  );
}

export default Registrationform;

3. 修正FormikContainer.js的属性拼写错误

避免其他表单出现同类问题,把错误的属性名validationschema改成Formik要求的validationSchema:

<Formik
  initialValues={initialValues}
  validationSchema={validationschema}
  onSubmit={onSubmit}
>

验证结果

修改完成后,表单输入内容、选择联系方式后提交按钮会自动变为可点击状态,点击按钮即可正常触发onSubmit逻辑,控制台会打印完整的表单数据。

内容的提问来源于stack exchange,提问作者Lizzy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 10:09:47