Formik setFieldValue 没有立即更新状态(1 渲染落后)

问题描述 投票:0回答:1

我有一个初始值为

{ 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>
  );
};
reactjs formik
1个回答
0
投票

这是您可以使用

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
做同样的事情。

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.