【发布时间】:2020-04-11 09:00:46
【问题描述】:
我在使用 GraphQL 突变处理快速数据库更新时遇到问题,特别是通过 Apollo Client 的 react-hooks 中的 useQuery 和 useMutation。我有一个表示来自数据库的数据的表,4 列是由复选框表示的布尔值,还有其他输入。选中该复选框会向数据库发送一个请求以将值设置为 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 整秒,这不是查看反映更改的可用响应时间。我已通过在内部管理复选框状态并在处理突变/查询并返回新数据之前对其进行更新来解决此问题。
这通常可以正常工作,但是当复选框或输入等连续更新非常快时会导致奇怪的行为,并且由于未触发它们的请求而可能会错过一些更新。更糟糕的是,因为我在前端管理状态,它可以显示不准确的信息,然后在最后一个查询返回时被覆盖。我可以在请求运行时禁用输入,但这感觉像是作弊。除非您专门尝试使用制表符和空格来尽可能快地进行检查,否则这并不是很明显,但这仍然不是很好。
答案是否使用 Apollo 提供的in-memory cache 来存储数据客户端以便可以立即更新?这听起来像是可行的,但我想知道如果更新发送得如此之快以至于它们相互干扰,我是否会遇到同样的问题,而且这意味着重写所有代码以在任何地方与数据库交互,即使这是不是问题(除非我弄错了),所以如果可能的话,我宁愿避免它。
是否有有效的方法来批量突变或以其他方式防止它们相互干扰?我的整个方法有缺陷吗?当更新是单独触发或由用户操作触发时,此模式可以正常工作,但它似乎根本无法很好地处理实时更新,因此非常感谢任何见解或替代方案!
【问题讨论】:
标签: javascript reactjs graphql react-apollo apollo-client