[英]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
useQuery
和useMutation
。 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.