我有一个初始值为
{ email: "", password: "", method: "manual" }
的formik表单设置。我想在 react-oauth/google 的 GoogleLogin 组件的 onSuccess 中将方法的值更改为“google”。更改值后,我使用 submitForm 方法手动提交表单。
我面临的问题是 setFieldValue 在第一次提交表单时没有改变。我不想使用单独的状态来处理这个。我在这里做错了什么?
export const Login: React.FC = () => {
const router = useRouter();
const [login] = useLoginMutation(); // First item is data state
return (
<Wrapper variant="small">
<Formik
enableReinitialize={true} // I tried setting it to false
initialValues={{ email: "", password: "", method: "manual" }}
onSubmit={async (values, { setErrors }) => {
console.log("form values", values);
const response = await login({
variables: { options: values },
update: (cache, { data }) => {
cache.writeQuery<MeQuery>({
query: MeDocument,
data: {
__typename: "Query",
me: data?.login.user,
},
});
cache.evict({ fieldName: "posts:{}" });
},
});
if (response.data?.login.errors) {
setErrors(toErrorMap(response.data.login.errors));
} else if (response.data?.login.user) {
if (typeof router.query.next === "string") {
router.push(router.query.next);
} else {
// worked
router.push("/");
}
}
}}
>
{({ isSubmitting, submitForm, setFieldValue, setFieldTouched }) => (
<Form>
<InputField name="email" label="Email" placeholder="[email protected]" />
<Box mt={4}>
<InputField
name="password"
label="Password"
placeholder="Password"
type={"password"}
/>
</Box>
<Flex>
<Box mt={4} ml={"auto"}>
<NextLink href="/forgot-password">
<Link textColor={"blue.600"} href="/forgot-password">
Forgot password?
</Link>
</NextLink>
</Box>
</Flex>
<Button
mt={4}
w="100%"
type="submit"
isLoading={isSubmitting}
colorScheme="teal"
onSubmit={(e) => {
e.preventDefault();
}}
>
Login
</Button>
<GoogleLogin
onSuccess={(response) => {
setFieldValue("method", "google");
setTimeout(() => setFieldTouched("method", true));
submitForm();
}}
onError={() => {}}
></GoogleLogin>
</Form>
)}
</Formik>
</Wrapper>
);
};
这是您可以使用
useFormikContext
采取的一种方法。
export function GoogleLoginSubmitOnSuccess() {
const { values, submitForm, setFieldValue } = useFormikContext();
useEffect(() => {
if (values.method === "google") {
submitForm()
}
}, [values, submitForm])
return (
<GoogleLogin
onSuccess={(response) => {
setFieldValue("method", "google");
}}
onError={() => {}}
/>
)
}
如果你想让它更可重用/可定制,你也可以用
useField
做同样的事情。