有没有办法在提交时更改表单值
is there a way to change form values on submit
我有一种情况,我想将两个按钮用作提交。
我怎样才能使邮政编码的值(在 formik 内)与选项的值(点击按钮)相结合,例如{“选项”:“成人”,“zip_code”:“00000”}
我找到了这个:https://github.com/formium/formik/issues/467#issuecomment-369833667
但它是针对 class 组件的,没有显示如何将按钮值转换为 formik 值...
import React, { useState, useEffect } 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); //using the hook useField, and destructuring
return(
<> {/*so we don't return any div tags - its just a react fragment */}
<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,...optionprops} = props
return(
<>
<button className={FORM_BUTTON} id={optionprops.id} onClick={()=>{optionprops.setButtonClick(true);
optionprops.setOption(optionprops.id)}}
>{optionprops.label}</button>
</>
)
};
export default function RegistrationForm(props) {
const {mainprops,userprops,...adoptprops} = props;
const [buttonClick, setButtonClick] = useState(false);
const [option, setOption] = useState('')
const allprops = {
mainprops,
userprops,
adoptprops,
buttonClick,
setButtonClick,
setOption
};
useEffect(()=>{
if (buttonClick){
alert(option)};
},[buttonClick])
// https://regex101.com/
const zipRegExp= /^([0-9]{5})$/;
//zipRegExp: only 5 digits
const zipRegExp_plus4= /^([0-9]{5})(?:[-\s]*([0-9]{4}))?$/;
return (
<Formik
initialValues={{
zip_code : ''
}}
validationSchema={Yup.object({
zip_code: Yup.string()
.min(5,'five digits needed')
.matches(zipRegExp, 'invalid zipcode')
.required('required field'),
})}
onSubmit={ (values, { setSubmitting, resetForm }) => {
setTimeout(() => {
// alert(JSON.stringify(values, null, 2));
resetForm();
setSubmitting(false);
}, 1000)
}}
>
{props => (
<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} groupa='pet' groupb='adopt' id='adult' label='adult'/>
<ButtonMaker {...allprops} groupa='pet' groupb='adopt' id='puppy' label='puppy'/>
</div>
</Form>
)}
</Formik>
)
}
我试过的其他东西:
将此添加到每个按钮:formkprops={props}
点击功能上的按钮制造商:formkprops.submitForm()
但是没用。
尝试以下操作:
import React, { useState, useEffect } 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); //using the hook useField, and destructuring
return(
<> {/*so we don't return any div tags - its just a react fragment */}
<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,...optionprops} = props
return(
<>
<button className={FORM_BUTTON} id={optionprops.id} onClick={()=>{optionprops.setButtonClick(true);
optionprops.setOption({"option": optionprops.id, "zipcode": optionprops.zip_code})}}
>{optionprops.label}</button>
</>
)
};
export default function RegistrationForm(props) {
const {mainprops,userprops,...adoptprops} = props;
const [buttonClick, setButtonClick] = useState(false);
const [option, setOption] = useState(null)
const allprops = {
mainprops,
userprops,
adoptprops,
buttonClick,
setButtonClick,
setOption
};
useEffect(()=>{
if (buttonClick){
alert(JSON.stringify(option, null, 4))};
},[buttonClick])
// https://regex101.com/
const zipRegExp= /^([0-9]{5})$/;
//zipRegExp: only 5 digits
const zipRegExp_plus4= /^([0-9]{5})(?:[-\s]*([0-9]{4}))?$/;
return (
<Formik
initialValues={{
zip_code : ''
}}
validationSchema={Yup.object({
zip_code: Yup.string()
.min(5,'five digits needed')
.matches(zipRegExp, 'invalid zipcode')
.required('required field'),
})}
onSubmit={ (values, { setSubmitting, resetForm }) => {
setTimeout(() => {
// alert(JSON.stringify(values, null, 2));
resetForm();
setSubmitting(false);
}, 1000)
}}
>
{props => (
<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} groupa='pet' groupb='adopt' id='adult' label='adult' zip_code={props.values.zip_code}/>
<ButtonMaker {...allprops} groupa='pet' groupb='adopt' id='puppy' label='puppy' zip_code={props.values.zip_code}/>
</div>
</Form>
)}
</Formik>
)
}
您需要创建一个选项 属性 并在调用 actionprops 的 setoption 函数时添加一个 zip_code 属性。为了在警报中显示它,您需要使用 JSON.stringify 函数来显示使用警报功能的选项。
**原始发帖者在评论部分要求的信息的解决方案**
您可以为您的应用程序创建状态管理或为此使用像 Redux 这样的库。在状态管理内部,您可以拥有一组类似于上面创建的对象。然后,您可以将要访问此数组的任何组件授予它。您还需要为用户提供最终提交以指示他们何时完成,或者用户必须选择所需数量的选项才能继续。
参考文献:
计算器溢出。如何提醒 javascript 对象。 。 (2021 年 10 月 10 日访问)。
我有一种情况,我想将两个按钮用作提交。
我怎样才能使邮政编码的值(在 formik 内)与选项的值(点击按钮)相结合,例如{“选项”:“成人”,“zip_code”:“00000”}
我找到了这个:https://github.com/formium/formik/issues/467#issuecomment-369833667
但它是针对 class 组件的,没有显示如何将按钮值转换为 formik 值...
import React, { useState, useEffect } 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); //using the hook useField, and destructuring
return(
<> {/*so we don't return any div tags - its just a react fragment */}
<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,...optionprops} = props
return(
<>
<button className={FORM_BUTTON} id={optionprops.id} onClick={()=>{optionprops.setButtonClick(true);
optionprops.setOption(optionprops.id)}}
>{optionprops.label}</button>
</>
)
};
export default function RegistrationForm(props) {
const {mainprops,userprops,...adoptprops} = props;
const [buttonClick, setButtonClick] = useState(false);
const [option, setOption] = useState('')
const allprops = {
mainprops,
userprops,
adoptprops,
buttonClick,
setButtonClick,
setOption
};
useEffect(()=>{
if (buttonClick){
alert(option)};
},[buttonClick])
// https://regex101.com/
const zipRegExp= /^([0-9]{5})$/;
//zipRegExp: only 5 digits
const zipRegExp_plus4= /^([0-9]{5})(?:[-\s]*([0-9]{4}))?$/;
return (
<Formik
initialValues={{
zip_code : ''
}}
validationSchema={Yup.object({
zip_code: Yup.string()
.min(5,'five digits needed')
.matches(zipRegExp, 'invalid zipcode')
.required('required field'),
})}
onSubmit={ (values, { setSubmitting, resetForm }) => {
setTimeout(() => {
// alert(JSON.stringify(values, null, 2));
resetForm();
setSubmitting(false);
}, 1000)
}}
>
{props => (
<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} groupa='pet' groupb='adopt' id='adult' label='adult'/>
<ButtonMaker {...allprops} groupa='pet' groupb='adopt' id='puppy' label='puppy'/>
</div>
</Form>
)}
</Formik>
)
}
我试过的其他东西:
将此添加到每个按钮:formkprops={props}
点击功能上的按钮制造商:formkprops.submitForm()
但是没用。
尝试以下操作:
import React, { useState, useEffect } 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); //using the hook useField, and destructuring
return(
<> {/*so we don't return any div tags - its just a react fragment */}
<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,...optionprops} = props
return(
<>
<button className={FORM_BUTTON} id={optionprops.id} onClick={()=>{optionprops.setButtonClick(true);
optionprops.setOption({"option": optionprops.id, "zipcode": optionprops.zip_code})}}
>{optionprops.label}</button>
</>
)
};
export default function RegistrationForm(props) {
const {mainprops,userprops,...adoptprops} = props;
const [buttonClick, setButtonClick] = useState(false);
const [option, setOption] = useState(null)
const allprops = {
mainprops,
userprops,
adoptprops,
buttonClick,
setButtonClick,
setOption
};
useEffect(()=>{
if (buttonClick){
alert(JSON.stringify(option, null, 4))};
},[buttonClick])
// https://regex101.com/
const zipRegExp= /^([0-9]{5})$/;
//zipRegExp: only 5 digits
const zipRegExp_plus4= /^([0-9]{5})(?:[-\s]*([0-9]{4}))?$/;
return (
<Formik
initialValues={{
zip_code : ''
}}
validationSchema={Yup.object({
zip_code: Yup.string()
.min(5,'five digits needed')
.matches(zipRegExp, 'invalid zipcode')
.required('required field'),
})}
onSubmit={ (values, { setSubmitting, resetForm }) => {
setTimeout(() => {
// alert(JSON.stringify(values, null, 2));
resetForm();
setSubmitting(false);
}, 1000)
}}
>
{props => (
<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} groupa='pet' groupb='adopt' id='adult' label='adult' zip_code={props.values.zip_code}/>
<ButtonMaker {...allprops} groupa='pet' groupb='adopt' id='puppy' label='puppy' zip_code={props.values.zip_code}/>
</div>
</Form>
)}
</Formik>
)
}
您需要创建一个选项 属性 并在调用 actionprops 的 setoption 函数时添加一个 zip_code 属性。为了在警报中显示它,您需要使用 JSON.stringify 函数来显示使用警报功能的选项。
**原始发帖者在评论部分要求的信息的解决方案**
您可以为您的应用程序创建状态管理或为此使用像 Redux 这样的库。在状态管理内部,您可以拥有一组类似于上面创建的对象。然后,您可以将要访问此数组的任何组件授予它。您还需要为用户提供最终提交以指示他们何时完成,或者用户必须选择所需数量的选项才能继续。
参考文献:
计算器溢出。如何提醒 javascript 对象。 。 (2021 年 10 月 10 日访问)。