简体   繁体   English

如何使用 Apollo Client 进行批量变异

[英]How to do Batch Mutations with Apollo Client

I try to use ApolloClient 2.1 with the new Mutation Component.我尝试将 ApolloClient 2.1 与新的 Mutation 组件一起使用。

Simple use cases are working but now I have something more complex.简单的用例正在起作用,但现在我有一些更复杂的东西。

What I want to achieve is to query data and put them in a list, then sort this list (here via react-sortable-hoc) and once sorted, I want to update the new position for all elements in the list.我想要实现的是查询数据并将它们放入列表中,然后对这个列表进行排序(这里是通过 react-sortable-hoc),一旦排序,我想更新列表中所有元素的新位置。

So the basis is something like this, which is working for simple Querying:所以基础是这样的,它适用于简单的查询:

const query = gql`
{
  items( order:{by:"position", direction:"desc"}) {
    id
    name
    position
  }
}`

const ItemView extends Component {
    onSortEnd = ({ oldIndex, newIndex }) => {
       console.log("Sort ended: ", oldIndex, newIndex);
    }

    render() {
     <Query query={query}>
        {({ loading, data, error }) => {
          if (loading) return <p>Loading...</p>;
          if (error) return <p>Error</p>;

          return (
            <ItemList items={data.items} onSortEnd={this.onSortEnd} />
          )
        }}
      </Query>
    }
}

Now I really struggle at a lot of parts in order to do the mutation.现在我真的在很多地方挣扎,以便进行突变。

I think I need to wrap the Mutation Component.我想我需要包装 Mutation 组件。 But how can I provide a GraphQL Query in there, because I want to do batch mutation with a similar query being fired multiple times, such as但是我怎样才能在那里提供一个 GraphQL 查询,因为我想通过多次触发类似的查询来进行批量突变,例如

mutation {
  updateItem1: updateItem(id: 457092155, input: {position: 1}) {
    item {
      id
    }
    ok 
    errors

  },
  updateItem2: updateItem(id: 54489270, input: {position: 2}) {
    item {
      id
    }
    ok 
    errors

  },
  ... // much more mutations, one for each item in the list
}

So my main question is, how do I pass a GraphQL mutation with dynamic amount of mutations to the Mutation component?所以我的主要问题是,如何将具有动态突变量的 GraphQL 突变传递给 Mutation 组件? Or should I do this completely differently?或者我应该完全不同地做这件事?

Thanks a lot for any hints非常感谢您的任何提示

You will have to compose multiple Mutations together in order to achieve this.为了实现这一点,您必须将多个 Mutation 组合在一起。 You can use react-adopt for this.您可以为此使用react-adopt They have even addressed this here https://github.com/pedronauck/react-adopt#leading-with-multiple-params .他们甚至在这里https://github.com/pedronauck/react-adopt#leading-with-multiple-params解决了这个问题。

You can also take a look at the discussion going on here https://github.com/apollographql/react-apollo/issues/1867 and jasonpaulos has an example demonstrating this with hooks你也可以看看这里的讨论https://github.com/apollographql/react-apollo/issues/1867jasonpaulos有一个例子用钩子演示这一点

Hi everyone!嗨,大家好! I believe that the new Apollo hooks, useQuery, useMutation, and useSubscription, adequately address this use case.我相信新的 Apollo 钩子 useQuery、useMutation 和 useSubscription 足以解决这个用例。 To demonstrate this, I have converted @Cridda's example that uses react-adopt and modified it to use @apollo/react-hooks here: https://codesandbox.io/s/apollo-and-react-hooks-4vril为了证明这一点,我已经转换了@Cridda 使用 react-adopt 的示例,并将其修改为在此处使用 @apollo/react-hooks: https : //codesandbox.io/s/apollo-and-react-hooks-4vril

This example is by no means perfect, but it serves as a demonstration of how hooks can massively simplify some use cases.这个例子绝不是完美的,但它演示了钩子如何大规模简化一些用例。

Hope this helps!希望这可以帮助!

I gave an answer here about Apollo Client's original Promise-based API, which may be easier to deal with for performing iterative mutations at a specific point (such as in a callback function). 在这里给出了有关Apollo Client原始基于Promise的API的答案,对于在特定点(例如在回调函数中)执行迭代突变,可能更易于处理。 Provided you have the ID's and corresponding positions, you could iterate over the data asynchronously and perform a mutation on each element. 如果您具有ID和相应的位置,则可以异步遍历数据并在每个元素上执行突变。

As Hemant mentioned already, the @compose annotation in Apollo 2.1 is the "correct" / conventional way to solve this problem.正如 Hemant 已经提到的,Apollo 2.1 中的 @compose 注释是解决这个问题的“正确”/传统方法。 If that doesn't work for you for whatever reason, there is possibly another cruder/hacky way to accomplish this:如果出于某种原因这对您不起作用,则可能有另一种更粗略/黑客的方法来实现此目的:

If your Item model has a parent model, you can mutate multiple nodes with one mutation by passing the children in as the array values to the connect / create / update actions.如果您的Item模型有一个父模型,您可以通过将子项作为数组值传递给connect / create / update操作来使用一个突变来改变多个节点。

The unfortunate limitation here is that there is no way to individually identify child nodes to be updated.不幸的是,这里的限制是无法单独识别要更新的子节点。 What I mean is that you can filter child Items to be mutated based on a criteria (like postition = 2) but that will only allow you to mutate the filtered items to the same state;我的意思是,你可以过滤子Items中发生突变根据标准(如postition = 2),但只允许你变异经过滤项,以相同的状态; you won't be able to update them differently from one another this way.您将无法以这种方式以不同方式更新它们。

If we allow ourselves one more crude step, you can delete the Item nodes that you wish to update before calling the update mutation - this will allow you to call the mutation with all of the updated items under the create: key in the mutation, which will allow you to specify each item to be created.如果我们允许自己更粗略的一步,您可以在调用更新突变之前删除您希望更新的 Item 节点 - 这将允许您使用create: key 下的所有更新项调用突变,其中将允许您指定要创建的每个项目。 In this way, the number of items you can create is only limited by the size of your request payload.这样,您可以创建的项目数量仅受请求负载大小的限制。

There are many cases where deleting and creating nodes is unacceptable (as opposed to updating them)...if you use this method then be sure there are no negative side effects to your use case(s) from deleting item data in this way.在很多情况下,删除和创建节点是不可接受的(而不是更新它们)……如果您使用此方法,请确保以这种方式删除项目数据不会对您的用例产生负面影响。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM