【问题标题】:How do you effectively batch GraphQL mutations using Apollo Client?您如何使用 Apollo Client 有效地批处理 GraphQL 突变?
【发布时间】:2020-04-11 09:00:46
【问题描述】:

我在使用 GraphQL 突变处理快速数据库更新时遇到问题,特别是通过 Apollo Client 的 react-hooks 中的 useQueryuseMutation。我有一个表示来自数据库的数据的表,4 列是由复选框表示的布尔值,还有其他输入。选中该复选框会向数据库发送一个请求以将值设置为 true,然后重新获取(通过命令式 refetchrefetchQueries)查询并更新表。

我的复选框组件:

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>
  );
};


但是,此周期可能需要 1-2 整秒,这不是查看反映更改的可用响应时间。我已通过在内部管理复选框状态并在处理突变/查询并返回新数据之前对其进行更新来解决此问题。

这通常可以正常工作,但是当复选框或输入等连续更新非常快时会导致奇怪的行为,并且由于未触发它们的请求而可能会错过一些更新。更糟糕的是,因为我在前端管理状态,它可以显示不准确的信息,然后在最后一个查询返回时被覆盖。我可以在请求运行时禁用输入,但这感觉像是作弊。除非您专门尝试使用制表符和空格来尽可能快地进行检查,否则这并不是很明显,但这仍然不是很好。

答案是否使用 Apollo 提供的in-memory cache 来存储数据客户端以便可以立即更新?这听起来像是可行的,但我想知道如果更新发送得如此之快以至于它们相互干扰,我是否会遇到同样的问题,而且这意味着重写所有代码以在任何地方与数据库交互,即使这是不是问题(除非我弄错了),所以如果可能的话,我宁愿避免它。

是否有有效的方法来批量突变或以其他方式防止它们相互干扰?我的整个方法有缺陷吗?当更新是单独触发或由用户操作触发时,此模式可以正常工作,但它似乎根本无法很好地处理实时更新,因此非常感谢任何见解或替代方案!

【问题讨论】:

    标签: javascript reactjs graphql react-apollo apollo-client


    【解决方案1】:

    听起来您应该利用 Apollo 的 optimistic UI features。您可以为您的突变指定一个optimisticResponse,它将用作服务器实际响应的占位符。这使您的 UI 可以平滑地更改以响应用户操作,即使需要一段时间才能从服务器获得响应。乐观响应应用于缓存本身,因此应用程序的任何其他部分也将立即反映突变。不幸的是,它不适用于refetch,但理想情况下,您应该使用update,而不是重新获取查询(而且optimisticResponse 确实适用于您提供的任何update 逻辑)。

    【讨论】:

    • 感谢您的回复!我曾考虑过使用它,但我认为(可能是错误的)管理复选框状态客户端基本上会提供相同的效果,因为乐观响应会立即呈现。但是,如果这将使响应周期更快,它可能会有所帮助!你能告诉我更多关于update 的信息吗?我似乎找不到它的文档,并且只知道refetchrefetchQueriesonCompleted 用于响应突变。
    • 在开始实施缓存之后,这绝对是一个很大的改进,而且没有我担心的那么困难。使用 Apollo 的乐观响应似乎不需要更新函数写入缓存,因为它已经将我的网络请求减少了 2/3。 UI 的响应速度不是很快,但这很容易成为组件库的问题;数据似乎总是准确的,这更重要。再次感谢!
    猜你喜欢
    • 2021-03-11
    • 2018-09-02
    • 2018-09-18
    • 1970-01-01
    • 1970-01-01
    • 2018-05-21
    • 1970-01-01
    • 2019-04-14
    • 2020-03-12
    相关资源
    最近更新 更多