React Apollo Hooks - 链突变

Posted

技术标签:

【中文标题】React Apollo Hooks - 链突变【英文标题】:React Apollo Hooks - Chain mutations 【发布时间】:2020-01-11 09:37:45 【问题描述】:

我有两个突变:

const [createRecord, data] = useMutation(createRecordQuery); 返回新建记录的ID const [saveValue, data: dataSave] = useMutation(saveValueQuery); 在记录中保存一些值

我的saveValue 突变需要记录 ID。如果我在新记录上打开我的表单,我还没有这个 ID,所以在提交时我需要先调用 createRecord 来检索 ID,然后再调用 saveValue 来保存我的记录中的值。

这种简单的方法行不通:

const onSave = async values => 
    if (!recordId) 
         // Call createRecord to retrieve recordId (code is simplified here) 
         const recordId = await createRecord();
    

    // Save my values
    return saveValue(variables: recordId, values);

但我真的不知道我应该如何处理第一个突变的loadingdata 并等待它运行第二个突变。

谢谢!

【问题讨论】:

【参考方案1】:

mutate 函数返回一个解析为突变响应数据的承诺,因此您应该能够简单地使用它来实现您想要的。

来自源代码:

如果您有兴趣在突变发生后执行某些操作 完成,不需要更新 store,使用 Promise 从client.mutate返回

我不确定为什么这在您的初始测试中不起作用,但我在本地尝试过它并按预期工作。您基本上应该能够执行您在问题中所写的内容。

【讨论】:

不幸的是,这并不像看起来那么简单。对于saveValue 突变,我需要recordId 和提交的值。我发现将它传递给onCompleted 函数的唯一方法是使用钩子状态const [valuesToSave, setValuesToSave] = useState([]); 并使用它是执行我的saveValue 突变的函数 在这种情况下,您可以使用与变量一起传入的更新选项。它的真正目的是允许您更新 apollo 存储(例如,将突变中的数据添加到其他查询以避免重新获取),但它也应该适用于此。像 onCompleted 一样,它将提供来自您的突变的数据作为参数。我已更新我的答案以包含详细信息。 对于update 部分,我接受您的回答。当我们利用不是为此目的而设计的东西时,这有点 hacky,但它完成了工作。恕我直言,有一种简单的方法来链接突变并将数据从一个到另一个传递是 Apollo 所缺乏的 实际上,我只是仔细检查了源代码并看到了评论'如果您有兴趣在突变完成后执行某些操作,并且您不需要更新商店,请使用从client.mutate'返回的 Promise。然后我在突变函数上使用 await 进行了测试,并成功获得了结果数据。你在这种方法上的尝试到底在哪里失败了? 你完全正确,它可以在 mutate 函数上使用简单的await...我以为我首先尝试了这个,我可能错过了一些东西。谢谢!【参考方案2】:

我不确定是否有办法推迟执行(以及我们不能暂停<Mutation>)。那么如何将第二部分移到单独的useEffect 中?

const [recordId, setRecordId] = useState(null);
const [values, setValues] = useState();
const onSave = async _values => 
    if (!recordId) 
         // Call createRecord to retrieve recordId (code is simplified here) 
         setRecordId(await createRecord());
    
    setValues(_values);

useEffect(() => 
  saveValue(variables: recordId, values);
, [recordId, _values]);

另一种解决方法是使用withApollo HOC:

function YourComponent( client:  mutate  ) 
 onSave = async values => 
   let recordId;
   if (!recordId) 
     recordId = await mutate(createRecordQuery);
   
   await mutate(saveValueQuery, values);
   // do something to let user know saving is done
 ;

export withApollo(YourComponent);

【讨论】:

以上是关于React Apollo Hooks - 链突变的主要内容,如果未能解决你的问题,请参考以下文章

Apollo react hooks 数组对象突变

如何在 react-apollo-hooks 和 formik 中使用突变?

有没有办法使用 @apollo/react-hooks 访问多个 graphql 突变的选项

React-Apollo-Hooks 使用Mutation 传递空变量?

使用 Jest 和 React 测试库测试 Apollo React Hooks

apollo graphql 突变 - JSON 输入意外结束