使用复选框启用和禁用提交按钮
Enabling and disabling submit button with checkboxes
我正在为我的 React 表单使用 Formik,这也是我的一个新手,我有一个带有两个复选框和一个默认禁用的提交按钮的表单。我需要找到一种方法来检查复选框是否已被选中。如果所有两个复选框都已选中,则提交按钮已启用,如果任何未选中,则提交按钮将保持禁用状态。
我的代码:
FormikWithRef:
import React, { useEffect, forwardRef, useImperativeHandle } from 'react';
import { Formik } from 'formik';
function FormikWithRef(props, ref) {
let formikPropObj = {};
useImperativeHandle(ref, () => formikPropObj);
useEffect(() => {
if (props.refSetter && props.invokable)
props.refSetter({
ref: ref.current,
invokableFunction: props.invokable,
});
}, []);
return (
<Formik {...props}>
{(formikProps) => {
formikPropObj = formikProps;
if (typeof props.children === 'function') {
return props.children(formikProps);
}
return props.children;
}}
</Formik>
);
}
export default forwardRef(FormikWithRef);
注册表单:
import React from 'react';
import PropTypes from 'prop-types';
import FormikWithRef from './FormikWithRef';
const RegisterForm = ({
formRef,
internalRef,
children,
initialValues,
validationSchema,
onSubmit,
enableReinitialize,
validateOnMount,
initialTouched,
invokable,
refSetter,
}) => {
return (
<FormikWithRef
enableReinitialize={enableReinitialize}
validateOnMount={validateOnMount}
initialTouched={initialTouched}
validateOnChange
validateOnBlur
initialValues={initialValues}
validationSchema={validationSchema}
onSubmit={onSubmit}
ref={formRef}
internalRef={internalRef}
invokable={invokable}
refSetter={refSetter}
>
{(props) => (
<form ref={internalRef} onSubmit={props.handleSubmit}>
{children}
</form>
)}
</FormikWithRef>
);
};
RegisterForm.propTypes = {
formRef: PropTypes.object,
children: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node]),
initialValues: PropTypes.object,
validationSchema: PropTypes.oneOfType([PropTypes.object, PropTypes.func]),
onSubmit: PropTypes.func,
enableReinitialize: PropTypes.bool,
validateOnMount: PropTypes.bool,
initialTouched: PropTypes.object,
internalRef: PropTypes.func,
handleSubmit: PropTypes.func,
invokable: PropTypes.func,
refSetter: PropTypes.func,
};
RegisterForm.defaultProps = {
formRef: null,
children: null,
initialValues: {},
validationSchema: null,
onSubmit: () => {},
enableReinitialize: false,
validateOnMount: false,
initialTouched: {},
internalRef: null,
handleSubmit: null,
invokable: null,
refSetter: null,
};
export default RegisterForm;
注册组件:
import React, { useState, useRef } from 'react';
import Registerform from './RegisterForm';
import useUserApi from './useUserApi';
const RegisterForm = () => {
const [submitting, setSubmitting] = useState(false);
const [isSubmitted, setIsSubmitted] = useState(false);
const [disableSubmit, setDisableSubmit] = useState(true);
const formRef = useRef();
const initialValues = {
cookies: false,
terms: false,
};
const {register} = useUserApi();
const submitRegisterForm = async (values) => {
const body = {
terms: values?.terms || null,
cookies: values?.cookies || null,
};
const res = await register(body);
return res;
};
const onFormSubmit = async (values, { setErrors }) => {
setSubmitting(true);
const result = await submitRegisterForm(values);
if (result && !(await checkErrors(result))) {
setSubmitting(false);
setIsSubmitted(true);
return true;
}
if (result.status === 500)
setErrors('A problem occurred submitting form.');
setIsSubmitted(false);
setSubmitting(false);
return false;
};
useEffect(() => {
if (isSubmitted) {
const historyScreen = reverse(`${routes.users}`);
history.push(historyScreen);
}
}, [isSubmitted]);
return initialValues ? (
<FormWrapper>
<RegisterForm
initialValues={initialValues}
onSubmit={onFormSubmit}
formRef={formRef}
>
<InputWrapper width="50%" verticalAlign="top">
<CheckBox
label={
<LabelText>I have agreed to terms</LabelText>
}
name="terms"
id="terms"
/>
</InputWrapper>
<InputWrapper width="50%" verticalAlign="top">
<CheckBox
label={
<LabelText>I agree to cookies.</LabelText>
}
name="cookies"
id="cookies"
/>
</InputWrapper>
<ButtonWrapper>
<SaveButton
type="submit"
buttonText="Register"
disabled={disableSubmit}
/>
</ButtonWrapper>
</Form>
</FormWrapper>
) : null;
}
export default RegisterForm;
您需要公开 RegisterForm 中的值。我假设 props
也应该有 values
。所以改变你的代码如下
<FormikWithRef
enableReinitialize={enableReinitialize}
validateOnMount={validateOnMount}
initialTouched={initialTouched}
validateOnChange
validateOnBlur
initialValues={initialValues}
validationSchema={validationSchema}
onSubmit={onSubmit}
ref={formRef}
internalRef={internalRef}
invokable={invokable}
refSetter={refSetter}
>
{(props) => (
<form ref={internalRef} onSubmit={props.handleSubmit}>
{children(props.values)} // make your children as a function
</form>
)}
</FormikWithRef>
现在,当您渲染 RegisterForm
时,您可以这样做
<RegisterForm
initialValues={initialValues}
onSubmit={onFormSubmit}
formRef={formRef}
>
{(values) => { // consume the value here
return (
.....
<ButtonWrapper>
<SaveButton type="submit" buttonText="Register" disabled={!(values.terms && values.cookies)} />
</ButtonWrapper>
)
}}
</RegisterForm>
我正在为我的 React 表单使用 Formik,这也是我的一个新手,我有一个带有两个复选框和一个默认禁用的提交按钮的表单。我需要找到一种方法来检查复选框是否已被选中。如果所有两个复选框都已选中,则提交按钮已启用,如果任何未选中,则提交按钮将保持禁用状态。
我的代码:
FormikWithRef:
import React, { useEffect, forwardRef, useImperativeHandle } from 'react';
import { Formik } from 'formik';
function FormikWithRef(props, ref) {
let formikPropObj = {};
useImperativeHandle(ref, () => formikPropObj);
useEffect(() => {
if (props.refSetter && props.invokable)
props.refSetter({
ref: ref.current,
invokableFunction: props.invokable,
});
}, []);
return (
<Formik {...props}>
{(formikProps) => {
formikPropObj = formikProps;
if (typeof props.children === 'function') {
return props.children(formikProps);
}
return props.children;
}}
</Formik>
);
}
export default forwardRef(FormikWithRef);
注册表单:
import React from 'react';
import PropTypes from 'prop-types';
import FormikWithRef from './FormikWithRef';
const RegisterForm = ({
formRef,
internalRef,
children,
initialValues,
validationSchema,
onSubmit,
enableReinitialize,
validateOnMount,
initialTouched,
invokable,
refSetter,
}) => {
return (
<FormikWithRef
enableReinitialize={enableReinitialize}
validateOnMount={validateOnMount}
initialTouched={initialTouched}
validateOnChange
validateOnBlur
initialValues={initialValues}
validationSchema={validationSchema}
onSubmit={onSubmit}
ref={formRef}
internalRef={internalRef}
invokable={invokable}
refSetter={refSetter}
>
{(props) => (
<form ref={internalRef} onSubmit={props.handleSubmit}>
{children}
</form>
)}
</FormikWithRef>
);
};
RegisterForm.propTypes = {
formRef: PropTypes.object,
children: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node]),
initialValues: PropTypes.object,
validationSchema: PropTypes.oneOfType([PropTypes.object, PropTypes.func]),
onSubmit: PropTypes.func,
enableReinitialize: PropTypes.bool,
validateOnMount: PropTypes.bool,
initialTouched: PropTypes.object,
internalRef: PropTypes.func,
handleSubmit: PropTypes.func,
invokable: PropTypes.func,
refSetter: PropTypes.func,
};
RegisterForm.defaultProps = {
formRef: null,
children: null,
initialValues: {},
validationSchema: null,
onSubmit: () => {},
enableReinitialize: false,
validateOnMount: false,
initialTouched: {},
internalRef: null,
handleSubmit: null,
invokable: null,
refSetter: null,
};
export default RegisterForm;
注册组件:
import React, { useState, useRef } from 'react';
import Registerform from './RegisterForm';
import useUserApi from './useUserApi';
const RegisterForm = () => {
const [submitting, setSubmitting] = useState(false);
const [isSubmitted, setIsSubmitted] = useState(false);
const [disableSubmit, setDisableSubmit] = useState(true);
const formRef = useRef();
const initialValues = {
cookies: false,
terms: false,
};
const {register} = useUserApi();
const submitRegisterForm = async (values) => {
const body = {
terms: values?.terms || null,
cookies: values?.cookies || null,
};
const res = await register(body);
return res;
};
const onFormSubmit = async (values, { setErrors }) => {
setSubmitting(true);
const result = await submitRegisterForm(values);
if (result && !(await checkErrors(result))) {
setSubmitting(false);
setIsSubmitted(true);
return true;
}
if (result.status === 500)
setErrors('A problem occurred submitting form.');
setIsSubmitted(false);
setSubmitting(false);
return false;
};
useEffect(() => {
if (isSubmitted) {
const historyScreen = reverse(`${routes.users}`);
history.push(historyScreen);
}
}, [isSubmitted]);
return initialValues ? (
<FormWrapper>
<RegisterForm
initialValues={initialValues}
onSubmit={onFormSubmit}
formRef={formRef}
>
<InputWrapper width="50%" verticalAlign="top">
<CheckBox
label={
<LabelText>I have agreed to terms</LabelText>
}
name="terms"
id="terms"
/>
</InputWrapper>
<InputWrapper width="50%" verticalAlign="top">
<CheckBox
label={
<LabelText>I agree to cookies.</LabelText>
}
name="cookies"
id="cookies"
/>
</InputWrapper>
<ButtonWrapper>
<SaveButton
type="submit"
buttonText="Register"
disabled={disableSubmit}
/>
</ButtonWrapper>
</Form>
</FormWrapper>
) : null;
}
export default RegisterForm;
您需要公开 RegisterForm 中的值。我假设 props
也应该有 values
。所以改变你的代码如下
<FormikWithRef
enableReinitialize={enableReinitialize}
validateOnMount={validateOnMount}
initialTouched={initialTouched}
validateOnChange
validateOnBlur
initialValues={initialValues}
validationSchema={validationSchema}
onSubmit={onSubmit}
ref={formRef}
internalRef={internalRef}
invokable={invokable}
refSetter={refSetter}
>
{(props) => (
<form ref={internalRef} onSubmit={props.handleSubmit}>
{children(props.values)} // make your children as a function
</form>
)}
</FormikWithRef>
现在,当您渲染 RegisterForm
时,您可以这样做
<RegisterForm
initialValues={initialValues}
onSubmit={onFormSubmit}
formRef={formRef}
>
{(values) => { // consume the value here
return (
.....
<ButtonWrapper>
<SaveButton type="submit" buttonText="Register" disabled={!(values.terms && values.cookies)} />
</ButtonWrapper>
)
}}
</RegisterForm>