You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在react-apollo-hooks与Formik中使用Mutation并传递表单参数?

解决Formik结合react-apollo-hooks的useMutation传参问题

你遇到的核心问题是对useMutation的用法理解有点偏差——其实它返回的mutation函数(也就是你这里的createUser)是可以动态接收变量参数的,不用在初始化钩子的时候就把variables写死。

咱们来一步步调整你的代码:

第一步:修改useMutation的初始化

初始化useMutation的时候,不需要提前写死variables,把这部分删掉,让它保持灵活:

const [createUser, { loading }] = useMutation(CREATE_USER_MUTATION);

第二步:在Formik的onSubmit里动态传参

在onSubmit函数里,你可以拿到Formik的values,直接把它(或者提取需要的字段)作为参数传给createUser。同时要处理提交状态的同步,比如在mutation完成后把setSubmitting设为false:

onSubmit={(values, { setSubmitting }) => {
  // 从values里提取需要的字段,传给createUser
  createUser({
    variables: {
      firstName: values.firstName,
      lastName: values.lastName,
      email: values.email,
      password: values.password,
    }
  })
  .then(() => {
    // 提交成功后的逻辑,比如跳转、提示
    console.log('用户创建成功');
  })
  .catch((error) => {
    // 处理错误
    console.error('创建用户失败:', error);
  })
  .finally(() => {
    // 不管成功失败,都结束提交状态
    setSubmitting(false);
  });
}}

完整修改后的代码

把这些改动整合到你的组件里,最终代码大概是这样:

const SignUp = () => {
  const classes = useStyles();
  // 初始化useMutation,不再硬编码variables
  const [createUser, { loading }] = useMutation(CREATE_USER_MUTATION);

  return (
    <Formik
      initialValues={{
        firstName: '',
        lastName: '',
        email: '',
        password: '',
        showPassword: false,
      }}
      // 在这里动态传递表单数据给mutation
      onSubmit={(values, { setSubmitting }) => {
        createUser({
          variables: {
            firstName: values.firstName,
            lastName: values.lastName,
            email: values.email,
            password: values.password,
          }
        })
        .then(() => {
          // 这里可以加成功后的逻辑,比如跳转到登录页
        })
        .catch(err => {
          // 处理错误,比如显示错误提示
          console.error(err);
        })
        .finally(() => {
          setSubmitting(false);
        });
      }}
      render={({submitForm, isSubmitting, values, setFieldValue}) => (
        <div>
          <h1>Sign up for a new account</h1>
          <Form className={classes.container}>
            <Field
              className={classes.textField}
              name="firstName"
              type="text"
              label="First name"
              margin="dense"
              variant="outlined"
              component={TextField}
            />
            {/* 补充其他字段的Field组件 */}
            <Field
              className={classes.textField}
              name="lastName"
              type="text"
              label="Last name"
              margin="dense"
              variant="outlined"
              component={TextField}
            />
            <Field
              className={classes.textField}
              name="email"
              type="email"
              label="Email"
              margin="dense"
              variant="outlined"
              component={TextField}
            />
            <Field
              className={classes.textField}
              name="password"
              type={values.showPassword ? "text" : "password"}
              label="Password"
              margin="dense"
              variant="outlined"
              component={TextField}
              InputProps={{
                endAdornment: (
                  <InputAdornment position="end">
                    <IconButton
                      onClick={() => setFieldValue("showPassword", !values.showPassword)}
                    >
                      {values.showPassword ? <VisibilityOff /> : <Visibility />}
                    </IconButton>
                  </InputAdornment>
                )
              }}
            />
          </Form>
          <Button
            variant="contained"
            color="primary"
            margin="dense"
            className={classes.button}
            disabled={isSubmitting || loading}
            onClick={submitForm}
          >
            {loading ? "Loading..." : "Sign Up"}
          </Button>
        </div>
      )}
    />
  );
};

额外优化点

  • 把loading状态也加到Button的disabled属性里,避免重复提交
  • 提交按钮的文字可以根据loading状态切换,提升用户体验
  • 补充完整所有表单字段的Field组件(你原来的代码里只写了firstName)

这样调整后,Formik的表单数据就能顺利传递给react-apollo-hooks的mutation了,完美解决你遇到的问题。

内容的提问来源于stack exchange,提问作者pizzae

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 09:13:43