useMutation返回的Mutation函数无法传递变量问题排查
使用useMutation时变量无法正常传递的问题
我在使用Apollo Client的useMutation钩子创建用户时,发现传递给createUser()函数的变量始终无法正常传递。该mutation在GraphQL服务器沙箱中可以正常运行,但前端调用时,DevTools显示请求的variables为空对象{}。
注册表单代码
import './SignUpForm.scss' import { loader } from 'graphql.macro' import { useMutation } from '@apollo/client' import { useState } from 'react' const CREATE_USER_MUTATION = loader('../../graphql/signup.graphql') export default function SignUpForm(props) { const [createUser, { data, loading, error }] = useMutation(CREATE_USER_MUTATION) const [formState, setFormState] = useState({ firstName: undefined, lastName: undefined, email: undefined, username: undefined, password: undefined }) const setAttr = (attr, e) => setFormState({ ...formState, [attr]: e.target.value }) return ( <> <form className='signUpForm' onSubmit={async (e) => { e.preventDefault(); await createUser({ variables: { data: formState } }) }}> <h2>Member registration</h2> <input placeholder='First name' autoComplete='on' id='firstNameInputField' onChange={ (e) => setAttr('firstName', e) }/> <input placeholder='Last name' autoComplete='on' id='lastNameInputField' onChange={ (e) => setAttr('lastName', e) }/> <input placeholder='Email' autoComplete='on' id='emailInputField' onChange={ (e) => setAttr('email', e) } /> <input placeholder='Username' autoComplete='on' id='usernameInputField' onChange={ (e) => setAttr('username', e) }/> <input placeholder='Password' type='password' id='passwordInputField' onChange={ (e) => setAttr('password', e) }/> <input type='submit' id='submitRegistrationButton'/> </form> <a href='/auth/signin'>Do you already have an account?</a> </> ) }
加载的GraphQL mutation文件(signup.graphql)
mutation signup($SignupInput: SignupInput!) { signup(data: $SignupInput) { user { username } } }
Schema定义
extend type Mutation { signup(data: SignupInput!): AuthenticationResult! } extend type Query { currentUser: User } type User { id: ID! email: String! firstName: String! lastName: String! username: String! salt: String! password: String! } input SignupInput { email: String! firstName: String! lastName: String! username: String! password: String! } type AuthenticationResult { user: User jwt: String authError: String }
沙箱中可正常运行的测试mutation
mutation CreateUserTest($SignupInput: SignupInput!) { signup(data: $SignupInput) { user { username } } }
DevTools网络请求结果
{ "operationName": "signup", "variables": {}, "query": "mutation signup($SignupInput: SignupInput!) {\n signup(data: $SignupInput) {\n user {\n username\n __typename\n }\n __typename\n }\n}\n" }
问题根源及修复方案
- 变量名不匹配:你的mutation定义中声明的变量是
$SignupInput,但调用createUser时传递的变量键是data,Apollo无法识别对应变量,导致variables为空。 - 初始状态值为undefined:表单初始字段值都是
undefined,而Schema中SignupInput的所有字段都是必填项(带!),即使变量传递成功,也可能触发验证失败。
修复步骤:
- 修改
createUser调用时的变量键,与mutation中的变量名保持一致:await createUser({ variables: { SignupInput: formState } }) - 可选优化:将表单初始状态的字段值设为空字符串,避免
undefined导致的必填字段验证问题:const [formState, setFormState] = useState({ firstName: '', lastName: '', email: '', username: '', password: '' })
修改后重新测试,DevTools中的variables会包含SignupInput对象,mutation就能正常接收参数完成用户创建。
内容的提问来源于stack exchange,提问作者Viktor Shevtsov
相关产品推荐
相关产品推荐

