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

How do you effectively batch GraphQL mutations using Apollo Client?

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

我的复选框组件:

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 整秒,这不是查看反映的更改的可用响应时间。我通过在内部管理复选框状态并在处理 mutations/queries 和返回新数据之前更新它来解决这个问题。

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

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

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

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