Formik提交时如何修改表单值 双提交按钮合并选中选项与邮政编码
具体修改步骤
- 移除组件外部冗余的状态管理
你不需要额外维护buttonClick、option两个React状态,直接复用Formik内置的状态管理能力即可,删除对应的useState、useEffect逻辑。 - 扩展Formik初始值
在Formik的initialValues中新增option字段,用来存储点击按钮对应的选项值:
initialValues={{ zip_code: '', option: '' }}
- 给按钮组件传递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' />
- 修改按钮点击逻辑
修改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> </> ) };
- 直接在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
相关产品推荐
相关产品推荐

