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

Formik提交时如何修改表单值 双提交按钮合并选中选项与邮政编码

具体修改步骤

  1. 移除组件外部冗余的状态管理
    你不需要额外维护buttonClick、option两个React状态,直接复用Formik内置的状态管理能力即可,删除对应的useState、useEffect逻辑。
  2. 扩展Formik初始值
    在Formik的initialValues中新增option字段,用来存储点击按钮对应的选项值:
initialValues={{
  zip_code: '',
  option: ''
}}
  1. 给按钮组件传递Formik核心方法
    在Formik的渲染回调中,把setFieldValue和submitForm两个方法传给ButtonMaker组件:
<ButtonMaker 
  {...allprops} 
  setFieldValue={props.setFieldValue}
  submitForm={props.submitForm}
  groupa='pet' 
  groupb='adopt' 
  id='adult' 
  label='adult'
/>
<ButtonMaker 
  {...allprops} 
  setFieldValue={props.setFieldValue}
  submitForm={props.submitForm}
  groupa='pet' 
  groupb='adopt' 
  id='puppy' 
  label='puppy'
/>
  1. 修改按钮点击逻辑
    修改ButtonMaker的点击事件,先给Formik的option字段赋值,再触发表单提交:
const ButtonMaker = (props) => {
  const {mainprops,userprops,adoptprops, setFieldValue, submitForm, ...optionprops} = props
  return(
    <>
    <button 
      className={FORM_BUTTON} 
      id={optionprops.id} 
      onClick={()=>{
        setFieldValue('option', optionprops.id)
        submitForm()
      }}
    >{optionprops.label}</button>
    </>
  )
};
  1. 直接在onSubmit中拿到合并后的数据
    此时onSubmit回调的values参数已经是你需要的格式,直接使用即可:
onSubmit={ (values, { setSubmitting, resetForm }) => {
  // values 格式为 {zip_code: "00000", option: "adult"/"puppy"}
  console.log(values)
  setTimeout(() => {
    resetForm();
    setSubmitting(false);
  }, 1000)
}}

完整修改后代码

import React from 'react';
import { Form, Formik, useField } from 'formik';
import * as Yup from 'yup';


const FORM_INPUT_BOX = "m-2 border border-gray-300 bg-white text-gray-700 placeholder-gray-400 shadow-sm text-base focus:outline-none focus:ring-2 focus:ring-yellow-500 focus:border-transparent"
const FORM_INPUT_LABEL = "ml-2 text-gray-700"
const FORM_INPUT_ERROR = "break-normal relative bottom-2 left-2 text-sm text-red-500"
const FORM_DROPDOWN = "m-2 focus:ring-yellow-500 border border-gray-300 focus:border-yellow-500 h-full border-transparent bg-transparent text-gray-500 sm:text-sm rounded"
export const FORM_BUTTON = "ml-2 mr-2 py-1 border border-transparent text-medium rounded-md text-white bg-gray-600 hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-gray-500"

const CustomTextInput = ({ label, ...props }) => {
    const [field, meta] =useField(props);
    return(
        <>
        <label htmlFor={props.id || props.name} className={FORM_INPUT_LABEL}> {label} </label>
        <input className={FORM_INPUT_BOX}{...field}{...props} />
        {meta.touched && meta.error ? (
            <div className={FORM_INPUT_ERROR}>{meta.error}</div>
        ) : null}
        </>
    )
}

const ButtonMaker = (props) => {
    const {mainprops,userprops,adoptprops, setFieldValue, submitForm, ...optionprops} = props
    return(
        <>
        <button 
          className={FORM_BUTTON} 
          id={optionprops.id} 
          onClick={()=>{
            setFieldValue('option', optionprops.id)
            submitForm()
          }}
        >{optionprops.label}</button>
        </>
    )
};

export default function RegistrationForm(props) {
    const {mainprops,userprops,...adoptprops} = props;
    const allprops = {
        mainprops,
        userprops,
        adoptprops
    };

    const zipRegExp= /^([0-9]{5})$/;
    const zipRegExp_plus4= /^([0-9]{5})(?:[-\s]*([0-9]{4}))?$/;

    return (
        <Formik
            initialValues={{
                zip_code: '',
                option: ''
            }}
            validationSchema={Yup.object({
                zip_code: Yup.string()
                    .min(5,'five digits needed')
                    .matches(zipRegExp, 'invalid zipcode')
                    .required('required field'),
            })}
            onSubmit={ (values, { setSubmitting, resetForm }) => {
                // 此处已经拿到符合要求的合并数据
                console.log(values)
                setTimeout(() => {
                    resetForm();
                    setSubmitting(false);
            }, 1000)
            }}
        >
            {formikProps => (
                <Form className='bg-white rounded px-8 py-8 mt-4 mb-4'>
                    <div className='flex justify-center align-center'>
                    <section className='m-2 w-52 flex flex-col border'>
                        <CustomTextInput label='Enter ZIP Code' name='zip_code' placeholder='zipcode' />
                    </section>
                    </div>
                    <br></br>
                    <div className='flex justify-center align-center'>
                    <ButtonMaker 
                      {...allprops} 
                      setFieldValue={formikProps.setFieldValue}
                      submitForm={formikProps.submitForm}
                      groupa='pet' 
                      groupb='adopt' 
                      id='adult' 
                      label='adult'
                    />
                    <ButtonMaker 
                      {...allprops} 
                      setFieldValue={formikProps.setFieldValue}
                      submitForm={formikProps.submitForm}
                      groupa='pet' 
                      groupb='adopt' 
                      id='puppy' 
                      label='puppy'
                    />
                    </div>
                </Form>
            )}
        </Formik>
    )
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 18:30:02