如何在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
相关产品推荐
相关产品推荐

