React中如何向GraphQL传递数组?类型匹配错误求助
待传递的数组结构
[{…}] 0: {id: 1, customers_top_competitors: 'asdfasd', top_competitors_url: 'https://www.asdfasd.com/', __typename: 'TopCompetitors'} length: 1 [[Prototype]]: Array(0)
JSON打印结果:
[{"id":1,"customers_top_competitors":"sdfasfdfasdfsd","top_competitors_url":"https://www.asdfdfasd.com/","__typename":"TopCompetitors"}]
现有代码
GraphQL Mutation定义
export const UPDATE_CUSTOMER_COMPETITORS = gql` mutation($customer_id: Int, $data: [TopCompetitorsInput]) { updateTopCompetitors(customer_id: $customer_id, data: $data) } `;
GraphQL输入模型
input TopCompetitorsInput { TopCompetitorsInputArray: [TopCompetitorsInputElement] } input TopCompetitorsInputElement { id: Int customers_top_competitors: String top_competitors_url: String }
数组获取逻辑
let { data: all_data } = useQuery(GET_TOP_COMPETITORS, { skip: !state.customers?.selected?.id, variables: { customer_id: state.customers?.selected?.id }, }); useEffect(() => { setcompetitorData(all_data?.getTopCompetitors); }, [all_data]);
添加数组元素逻辑
const AddCompetitor = () => { if(highestCompetitorID){ setcompetitorData((competitorData) => [...competitorData, {id: highestCompetitorID, customers_top_competitors: '', top_competitors_url: ''}]) sethighestCompetitorID(competitorData[competitorData.length - 1].id + 1) }else { setcompetitorData((competitorData) => [...competitorData, {id: 1, customers_top_competitors: '', top_competitors_url: ''}]); sethighestCompetitorID(competitorData[competitorData.length - 1].id + 1) } }
错误信息
react_devtools_backend.js:4026 [GraphQL error]: Message: Variable "$data" got invalid value
{ 0: { id: 1, customers_top_competitors: "asdfasd", top_competitors_url: "https://www.asdfasd.com/",
__typename: "TopCompetitors" } }; Field "0" is not defined by type TopCompetitorsInput., Location: [object Object], Path: undefined
当前临时解决方案
通过循环逐个传递数组元素实现功能:
<Button color="orange" type="submit" onClick={() => { for(let x = 0; x < competitorData?.length; x++) { updateCustomerCompetitors({ variables: { customer_id: state.customers?.selected?.id, data: omit(competitorData[x], ["__typename"]) } }) } } } > Submit </Button>
解决方法
1. 修正变量传递结构(无需修改后端)
问题核心是:你的GraphQL输入模型TopCompetitorsInput要求接收一个TopCompetitorsInputArray字段,而非直接传递数组。当前直接传数组会被解析为带索引键的对象(如{0: {...}}),但TopCompetitorsInput未定义索引字段,因此报错。
修改提交逻辑,按模型要求的结构传递数据,同时移除元素的__typename:
<Button color="orange" type="submit" onClick={() => { // 处理数组:移除每个元素的__typename const processedData = competitorData?.map(item => omit(item, ["__typename"])) || []; updateCustomerCompetitors({ variables: { customer_id: state.customers?.selected?.id, data: { TopCompetitorsInputArray: processedData } // 按输入模型结构包裹数组 } }) } } > Submit </Button>
2. 简化输入模型(需后端配合)
如果后端允许调整,建议简化输入模型,让updateTopCompetitors的data参数直接接收元素数组,这样传递逻辑更直观:
// 修改后的输入模型 input TopCompetitorsInputElement { id: Int customers_top_competitors: String top_competitors_url: String } // 修改后的Mutation定义 export const UPDATE_CUSTOMER_COMPETITORS = gql` mutation($customer_id: Int, $data: [TopCompetitorsInputElement]) { updateTopCompetitors(customer_id: $customer_id, data: $data) } `;
此时提交逻辑简化为:
<Button color="orange" type="submit" onClick={() => { const processedData = competitorData?.map(item => omit(item, ["__typename"])) || []; updateCustomerCompetitors({ variables: { customer_id: state.customers?.selected?.id, data: processedData } }) } } > Submit </Button>
3. 修复AddCompetitor的ID计算问题
当前AddCompetitor中更新highestCompetitorID时,使用的是更新前的数组数据,会导致ID计算错误,改为函数式更新:
const AddCompetitor = () => { setcompetitorData((prevData) => { const newId = highestCompetitorID || 1; const newData = [...prevData, { id: newId, customers_top_competitors: '', top_competitors_url: '' }]; sethighestCompetitorID(newId + 1); return newData; }); }
内容的提问来源于stack exchange,提问作者Andrew Kloos

