在redux应用程序中,我们如何在表单提交后重置"react-google-recaptcha"复选



所以我有一个redux应用程序,它有一个名为LoginForm的文件,(只是表单元素),我有另一个名为LoginFormContainer的文件(formik负责)的表单值。在这种情况下,如何重置验证码呢?考虑到ref在LoginForm文件上,

尝试ref方法,但我无法让它工作,因为这是两个文件,在ref方面对彼此一无所知。

这是我使用react-google-recaptcha创建的组件

import React from "react";
import ReCAPTCHA from "react-google-recaptcha";
interface OwnProps {
onChange(value: any): any;
}
const ReCaptcha: React.FunctionComponent<OwnProps> = (props) => {
const { onChange } = props;
const recaptchaRef = React.useRef<ReCAPTCHA>(null);
const siteKey = String(process.env.REACT_APP_GOOGLE_SITE_KEY);
return (
<>
<ReCAPTCHA
ref={recaptchaRef}
sitekey={siteKey}
size="normal"
onChange={onChange}
theme={"dark"}
/>
</>
);
};
export default ReCaptcha;

这是收集数据的表单

import { Field, Form, InjectedFormikProps } from "formik";
import * as React from "react";

export const LoginForm: React.FunctionComponent<
InjectedFormikProps<{}, LoginFormValues>
> = (props) => {
const { isSubmitting, setFieldValue } = props;

function onChangeCAPTCHA(value: any) {
setFieldValue("captchaToken", value);
}

return (
<Form>
<FormFieldsWrapper>
<Field type="email" label="Email" name="email" component={TextInput} />
</FormFieldsWrapper>
<FormFieldsWrapper>
<Field
type="password"
label="Password"
name="password"
component={TextInput}
/>
</FormFieldsWrapper>
<FormFieldsWrapper>
<ReCaptcha onChange={onChangeCAPTCHA} />
</FormFieldsWrapper>
<FormFieldsWrapper>
<Button
fullWidth={true}
primary={true}
disabled={isSubmitting}
loading={isSubmitting}
type="submit"
style={{ marginTop: 20 }}
>
Login
</Button>
</FormFieldsWrapper>
</Form>
);
};

export default LoginForm;

这是将表单值发送到后端的容器

import { withFormik } from "formik";
...
interface PropsFromState {
authenticated: boolean;
location: Location;
}
interface PropsFromDispatch {
loginPromise: typeof loginPromise;
}
const schema = Yup.object().shape({
email: Yup.string()
.email("Please enter a valid email")
.required("Email is required"),
password: Yup.string().required("Password is required"),
captchaToken: Yup.string().required("Please select CAPTCHA"),
});
type AllProps = PropsFromState & PropsFromDispatch;
class LoginFormContainer extends React.Component<AllProps> {
public render() {
let from = { pathname: "/tenants", search: this.props.location.search };
const { authenticated } = this.props;
if (this.props.location.state && this.props.location.state.from) {
from = this.props.location.state.from;
}
if (!authenticated) {
return <Wrapper>{this.renderForm()}</Wrapper>;
}
return <Redirect to={from} />;
}
private renderForm() {
const formikEnhancer = withFormik<{}, LoginFormValues>({
displayName: "LoginForm",
handleSubmit: async (values, { setSubmitting }) => {
try {
await this.props.loginPromise(values);
} catch (error) {
console.log(error);
} finally {
setSubmitting(false);
}
},
mapPropsToValues: () => ({ email: "", password: "", captchaToken: null }),
validationSchema: schema,
});
const EnhancedLoginForm = formikEnhancer(LoginForm);
return <EnhancedLoginForm />;
}
}
const mapStateToProps = ({ auth, router }: ApplicationState) => ({
authenticated: auth.authenticated,
location: router.location,
});
const mapDispatchToProps = (dispatch: Dispatch) => ({
...bindPromiseCreators({ loginPromise }, dispatch),
});
export default connect(
mapStateToProps,
mapDispatchToProps
)(LoginFormContainer) as any;

你似乎有两种方法:

方法1:

//LoginForm.js
const LoginForm = () => {
const recaptchaRef = React.useRef<ReCAPTCHA>(null);
return (
<Form onSubmit={() => recaptchaRef.current.reset()}>
...
<Recaptcha ref={recaptchaRef} onChange={onChange} />
....
</Form>
);
}

方法2:

// LoginForm.js
const LoginForm = () => {
return (
<FormWithRecaptcha>
...
</FormWithRecaptcha>
);
}
//FormWithRecaptcha.js
const FormWithRecaptcha = (props) => {
const recaptchaRef = React.useRef<ReCAPTCHA>(null);
return (
<Form onSubmit={() => recaptchaRef.current.reset()}>
<Recaptcha ref={recaptchaRef} onChange={onChange} />
{props.children}
</Form>
);
}

最新更新