简体   繁体   English

你如何使用 Apollo Client 有效地批量处理 GraphQL 突变?

[英]How do you effectively batch GraphQL mutations using Apollo Client?

I'm having an issue handling rapid database updates using GraphQL mutations, specifically through useQuery and useMutation from Apollo Client's react-hooks .我在使用 GraphQL 突变处理快速数据库更新时遇到问题,特别是通过 Apollo Client 的react-hooks useQueryuseMutation I have a table which represents data from the DB, 4 columns are boolean values represented by checkboxes, with other inputs as well.我有一个表示来自 DB 的数据的表,4 列是由复选框表示的布尔值,还有其他输入。 Checking the checkbox dispatches a request to the database to set the value to true, then refetches (either through refetch imperatively or refetchQueries ) the query and updates the table.勾选复选框(通过任一调度到数据库的请求,以将值设置为真,则重新提取refetch势在必行或refetchQueries )查询和更新表。

My Checkbox component:我的复选框组件:

export const TableCheckbox: <T extends VasaRecord & DomainEntity, K extends keyof T>(props: TableInputProps<T, K>) => ReactElement = ({
  value, // Boolean column value
  record, //Entire data record
  dataIndex //Accessor on record where value is located
}) => {
  const [checked, setChecked] = useState<boolean>(value as boolean);

  // useMutation function
  const { updateEntity } = useContext(
    TrackerContext
  );

  useEffect(() => {
    setChecked(value as boolean);
  }, [value]);

  const handleCheck = (e: CheckboxChangeEvent) => {
    const val = e.target.checked;
    setChecked(val);
    const newRecord = { id: record.key, [dataIndex]: val };

      updateEntity({
        variables: { entityTracker: JSON.stringify(newRecord) }
      }).then((res: any) => {
        console.log(res);
      });

  };

  return (
    <span className="checkbox-wrapper" onClick={disableClickSelect}>
      <Checkbox checked={checked} onChange={handleCheck} />
    </span>
  );
};


However, this cycle can take 1-2 full seconds, which is not a usable response time to see a change reflected.但是,此周期可能需要 1-2 整秒,这不是查看反映更改的可用响应时间。 I've addressed this by managing the checkbox state internally and updating it before the mutations/queries are processed and the new data returned.我通过在内部管理复选框状态并在处理突变/查询和返回新数据之前更新它来解决这个问题。

This mostly works fine, but causes strange behavior when checkboxes or inputs etc. are updated very quickly in succession and some updates can be missed as their requests are not fired.这通常可以正常工作,但是当复选框或输入等非常快速地连续更新时会导致奇怪的行为,并且由于它们的请求没有被触发,可能会错过一些更新。 Even worse, because I'm managing the state on the front end, it can show inaccurate information that's then overwritten when the last query returns.更糟糕的是,因为我在前端管理状态,所以它可能会显示不准确的信息,然后在最后一个查询返回时覆盖这些信息。 I could disable the inputs while a request is running, but that feels like cheating.我可以在请求运行时禁用输入,但这感觉像是在作弊。 It's not really noticeable unless you're specifically trying to use tab and space to check as fast as humanly possible, but still isn't good.除非您专门尝试使用制表符和空格键来尽可能快地进行检查,否则这并不是很明显,但仍然不是很好。

Is the answer using the in-memory cache provided by Apollo to store the data clientside so it can be updated instantly?答案是否使用 Apollo 提供的内存缓存来存储客户端数据,以便可以立即更新? This sounds like it could work, but I wonder if I would have the same problem if updates are dispatched so rapidly that they interfere with one another, plus it would mean rewriting all of the code for interacting with the database everywhere, even where this is not an issue (unless I'm mistaken), so I'd rather avoid it if possible.这听起来似乎可行,但我想知道如果更新的调度速度如此之快以至于它们相互干扰,我是否会遇到同样的问题,另外这意味着重写所有代码以在任何地方与数据库交互,即使是在此处不是问题(除非我弄错了),所以如果可能的话,我宁愿避免它。

Is there an effective way to batch mutations or otherwise prevent them from interfering with each other?有没有一种有效的方法来批量突变或以其他方式防止它们相互干扰? Is my entire approach flawed?我的整个方法有缺陷吗? This pattern works fine when updates are triggered individually or by a user action, but it doesn't seem to handle real-time updates well at all, so any insight or alternatives are much appreciated!当单独或由用户操作触发更新时,此模式工作正常,但它似乎根本不能很好地处理实时更新,因此非常感谢任何见解或替代方案!

It sounds like you should take advantage of Apollo's optimistic UI features .听起来您应该利用 Apollo 的乐观 UI 功能 You can specify an optimisticResponse for your mutation which will be used as a placeholder for the actual response from the server.您可以为您的突变指定一个optimisticResponse响应,它将用作来自服务器的实际响应的占位符。 This allows your UI to smoothly change in response to user actions even when it takes a while to get a response from the server.这允许您的 UI 平滑地响应用户操作而改变,即使需要一段时间才能从服务器获得响应。 The optimistic response is applied to the cache itself, so any other part of your app will immediately reflect the mutation as well.乐观响应应用于缓存本身,因此应用程序的任何其他部分也会立即反映变化。 Unfortunately, it will not work with refetch , but ideally you should be using update instead of refetching queries anyway (and optimisticResponse does work with whatever update logic you provide).不幸的是,它不适用于refetch ,但理想情况下,您应该使用update而不是 refetching 查询(而且optimizeResponse确实适用于您提供的任何update逻辑)。

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

相关问题 如何在Vanilla JS中使用Apollo Client创建GraphQL订阅 - How do I create a GraphQL subscription with Apollo Client in Vanilla JS 反应中的奇怪错误 - 使用阿波罗/客户端 - graphql - Weird error in react - using apollo/client - graphql 如何使用Apollo为突变实现auth指令? - How do I implement auth directive for mutations with Apollo? Apollo GraphQL 不断接收请求,没有进行查询或突变 - Apollo GraphQL keeps receiving requests with no queries or mutations being made 如何在GraphQL中进行相关的突变? - How to make related mutations in GraphQL? 如何在Apollo / GraphQL中使用Styleguidist进行配置 - How to configure using Styleguidist with Apollo/GraphQL 在 Javascript 中使用 GraphQL + Apollo 客户端查询具有部分字符串匹配的数据 - Query data with partial string match using GraphQL + Apollo client in Javascript 使用 Apollo 客户端时,GraphQL 突变未发送到请求? - GraphQL mutation not being sent to request when using Apollo client? 使用graphql和apollo客户端获取数据时将数据存储在状态中 - storing data in state when data is fetched using graphql and apollo client 如何在React中的Apollo客户端突变组件中包装GraphQL突变 - How to wrap GraphQL mutation in Apollo client mutation component in React
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM