React对接GraphQL服务器:修复‘Cannot read property 'id' of undefined’突变错误
我帮你分析了下,你遇到的核心问题主要有两个:变量传递格式和GraphQL Schema定义不匹配,还有**items字段类型不对**,这俩问题导致Mutation执行异常,最后触发了id未定义的报错。下面一步步帮你修复:
1. 先把Mutation变量的传递格式改对
你的GraphQL Mutation定义明确要求接收一个$input: UserInput参数,但你调用的时候直接把各个字段平铺传了,没包装成input对象。Apollo Client会因为变量结构不匹配,导致Mutation执行失败,后端返回错误后,前端拿到的createUser结果就是undefined,自然会出现读取id的报错。
修改addUser.js里的onSubmit函数:
const onSubmit = e => { e.preventDefault(); // 把所有字段包装成input对象,完全匹配Mutation定义的参数结构 props.addUserMutation({ variables: { input: { firstName, lastName, email, gender, // 这里items需要处理成符合要求的对象数组,下面详细说 items: items ? [{ text: items, timeISO: new Date().toISOString(), title: "默认标题" }] : [] } } }); // 你的后续逻辑... };
2. 修正items字段的类型匹配
你的Mutation里items是一个包含text、timeISO、title的对象数组,但当前代码里items是个字符串状态,直接传的话后端根本解析不了,肯定会导致创建用户失败。
如果你的需求是让用户输入单个item的文本,那可以把输入的字符串转换成符合要求的对象数组(上面的代码已经做了简单处理,你可以根据实际需求调整,比如要支持多个item的话,就得改成数组输入的形式)。
3. 建议在Mutation里加上id返回字段(可选但很有用)
如果后端创建用户后会返回id字段,建议在你的Mutation查询里加上id,这样前端能拿到完整的用户数据,也能避免后续可能出现的类似报错:
export const addUserMutation = gql` mutation createUser($input: UserInput) { createUser(input: $input) { id # 加上这个字段 firstName lastName email items { text timeISO title } } } `;
4. 关于控制台渲染标签和教程不一致的问题
你提到控制台渲染标签和教程不同,大概率是Apollo Client的版本差异导致的。你现在用的是比较老的react-apollo包(依赖graphql高阶组件、compose这些),而新版Apollo Client已经换成@apollo/client,用useMutation钩子来写了。如果要对齐教程:
- 要是教程用的是新版,你可以迁移到
@apollo/client,用useMutation替代高阶组件,写法大概是这样:
// addUser.js 新版写法示例 import { useMutation } from '@apollo/client'; import { addUserMutation } from '../queries/queries'; const AddUser = () => { const [addUser] = useMutation(addUserMutation); // ...你的状态定义 const onSubmit = e => { e.preventDefault(); addUser({ variables: { input: { firstName, lastName, email, gender, items: [...] } } }); }; // ...你的渲染逻辑 };
- 要是你想继续用老版本,那得确保
react-apollo和apollo-client的版本和教程完全一致,不然很容易出现兼容性问题。
最后验证一下
改完之后,重启前后端服务,提交表单的时候可以用Apollo DevTools或者GraphQL Playground看看请求日志,确认变量格式是对的,后端返回了正常的用户数据,这样那个id未定义的报错就应该解决啦。
内容的提问来源于stack exchange,提问作者Nikola Golubović

