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

标签 javascript reactjs graphql react-apollo apollo-client

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

我的复选框组件:

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

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

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

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

最佳答案

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

关于javascript - 如何使用 Apollo Client 有效地批处理 GraphQL 突变?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59398282/

相关文章:

reactjs - 在 Relay Modern 中处理身份验证

javascript - IE : Problem with local content and Flash

javascript - 使用 Node 和 Socket.io 我试图传递一个简单的数组,但我什么也没得到。我错过了什么?

javascript - 如何合并两个几乎相同的数组/对象(使用下划线js或类似的库)?

reactjs - 基于表单字段的zod条件验证

javascript - 如何使用react和react-apollo从graphql服务器获取数据?

javascript - 即使按正确顺序包含所有必要的脚本后,AngularJS-Slick 也无法正常工作

java - 将 JS 数组作为 List<> 传递给 Spring MVC Controller

reactjs - 无法在 useEffect Hook 内设置状态

graphql - 将 GraphQL 类型模块化到单独的文件中