Apollo 客户端延迟重新获取
Apollo Client lazy refetch
在Apollo Client v3
React 实现中,我使用钩子来使用订阅。当我从订阅中收到数据时,我想重新获取查询,但前提是查询先前已执行并在缓存中。有办法实现吗?
我从延迟查询开始,然后在收到订阅数据时手动检查缓存,然后尝试执行延迟查询和重新获取。它有效,但感觉笨重...
export const useMyStuffLazyRefetch = () => {
const [refetchNeeded, setRefetchNeeded] = useState<boolean>(false);
const client = useApolloClient();
const [getMyStuff, { data, refetch }] = useLazyQuery<IStuffData>(GET_MY_STUFF);
useEffect(() => {
if (refetchNeeded) {
setRefetchNeeded(false);
refetch();
}
}, [refetchNeeded]);
const refetchIfNeeded = async () => {
const stuffData = client.cache.readQuery<IStuffData>({ query: GET_MY_STUFF });
if (!stuffData?.myStuff?.length) return;
getMyStuff();
setRefetchNeeded(true);
}
return {
refetchIfNeeded: refetchIfNeeded
};
}
useLazyQuery
有一个prop叫做called
,这是一个布尔值,表示是否调用了查询函数,
也许你可以试试这个:
export const useMyStuffLazyRefetch = () => {
const [refetchNeeded, setRefetchNeeded] = useState<boolean>(false);
const client = useApolloClient();
const [getMyStuff, { data, refetch, called }] = useLazyQuery<IStuffData>(GET_MY_STUFF);
useEffect(() => {
if (refetchNeeded) {
setRefetchNeeded(false);
if (called) {
refetch();
}
else {
getMyStuff()
}
}
}, [refetchNeeded, called]);
const refetchIfNeeded = async () => {
const stuffData = client.cache.readQuery<IStuffData>({ query: GET_MY_STUFF });
if (!stuffData?.myStuff?.length) return;
getMyStuff();
setRefetchNeeded(true);
}
return {
refetchIfNeeded: refetchIfNeeded
};
}
以防这对某人有所帮助。我创建了一个单独的挂钩,因此使用起来不那么碍眼。
如果数据在缓存中,这是重新获取的挂钩。如果数据不在缓存中,Apollo Client
错误而不是返回类似 undefined
或 null
的内容
import { useState, useEffect } from "react";
import { OperationVariables, DocumentNode, LazyQueryHookOptions, useApolloClient, useLazyQuery } from "@apollo/client";
export default function useLazyRefetch <TData = any, TVariables = OperationVariables>(query: DocumentNode, options?: LazyQueryHookOptions<TData, TVariables>) {
const [refetchNeeded, setRefetchNeeded] = useState<boolean>(false);
const [loadData, { refetch }] = useLazyQuery(query, options);
const client = useApolloClient();
useEffect(() => {
if (refetchNeeded) {
setRefetchNeeded(false);
refetch();
}
}, [refetchNeeded]);
const refetchIfNeeded = (variables: TVariables) => {
try {
const cachecData = client.cache.readQuery<
TData,
TVariables
>({
query: query,
variables: variables
});
if (!cachecData) return;
loadData({ variables: variables });
setRefetchNeeded(true);
}
catch {}
};
return {
refetchIfNeeded: refetchIfNeeded
};
}
以及钩子使用示例:
const { refetchIfNeeded } = useLazyRefetch<
IStuffData,
{ dataId?: string }
>(GET_MY_STUFF);
//... And then you can just call it when you need to
refetchIfNeeded({ dataId: "foo" });
打字稿在您的
中抱怨
useEffect(() => {
if (refetchNeeded) {
setRefetchNeeded(false);
refetch();
}
}, [refetchNeeded]);
refetch() says - Cannot invoke an object which is possibly 'undefined'.ts(2722)
const refetch: ((variables?: Partial<TVariables> | undefined) => Promise<ApolloQueryResult<TData>>) | undefined
and in [refetchNeeded] dependency -
React Hook useEffect 缺少依赖项:'refetch'。包含它或删除依赖项数组。eslintreact-hooks/exhaustive-deps
const refetchNeeded:布尔值
在Apollo Client v3
React 实现中,我使用钩子来使用订阅。当我从订阅中收到数据时,我想重新获取查询,但前提是查询先前已执行并在缓存中。有办法实现吗?
我从延迟查询开始,然后在收到订阅数据时手动检查缓存,然后尝试执行延迟查询和重新获取。它有效,但感觉笨重...
export const useMyStuffLazyRefetch = () => {
const [refetchNeeded, setRefetchNeeded] = useState<boolean>(false);
const client = useApolloClient();
const [getMyStuff, { data, refetch }] = useLazyQuery<IStuffData>(GET_MY_STUFF);
useEffect(() => {
if (refetchNeeded) {
setRefetchNeeded(false);
refetch();
}
}, [refetchNeeded]);
const refetchIfNeeded = async () => {
const stuffData = client.cache.readQuery<IStuffData>({ query: GET_MY_STUFF });
if (!stuffData?.myStuff?.length) return;
getMyStuff();
setRefetchNeeded(true);
}
return {
refetchIfNeeded: refetchIfNeeded
};
}
useLazyQuery
有一个prop叫做called
,这是一个布尔值,表示是否调用了查询函数,
也许你可以试试这个:
export const useMyStuffLazyRefetch = () => {
const [refetchNeeded, setRefetchNeeded] = useState<boolean>(false);
const client = useApolloClient();
const [getMyStuff, { data, refetch, called }] = useLazyQuery<IStuffData>(GET_MY_STUFF);
useEffect(() => {
if (refetchNeeded) {
setRefetchNeeded(false);
if (called) {
refetch();
}
else {
getMyStuff()
}
}
}, [refetchNeeded, called]);
const refetchIfNeeded = async () => {
const stuffData = client.cache.readQuery<IStuffData>({ query: GET_MY_STUFF });
if (!stuffData?.myStuff?.length) return;
getMyStuff();
setRefetchNeeded(true);
}
return {
refetchIfNeeded: refetchIfNeeded
};
}
以防这对某人有所帮助。我创建了一个单独的挂钩,因此使用起来不那么碍眼。
如果数据在缓存中,这是重新获取的挂钩。如果数据不在缓存中,Apollo Client
错误而不是返回类似 undefined
或 null
import { useState, useEffect } from "react";
import { OperationVariables, DocumentNode, LazyQueryHookOptions, useApolloClient, useLazyQuery } from "@apollo/client";
export default function useLazyRefetch <TData = any, TVariables = OperationVariables>(query: DocumentNode, options?: LazyQueryHookOptions<TData, TVariables>) {
const [refetchNeeded, setRefetchNeeded] = useState<boolean>(false);
const [loadData, { refetch }] = useLazyQuery(query, options);
const client = useApolloClient();
useEffect(() => {
if (refetchNeeded) {
setRefetchNeeded(false);
refetch();
}
}, [refetchNeeded]);
const refetchIfNeeded = (variables: TVariables) => {
try {
const cachecData = client.cache.readQuery<
TData,
TVariables
>({
query: query,
variables: variables
});
if (!cachecData) return;
loadData({ variables: variables });
setRefetchNeeded(true);
}
catch {}
};
return {
refetchIfNeeded: refetchIfNeeded
};
}
以及钩子使用示例:
const { refetchIfNeeded } = useLazyRefetch<
IStuffData,
{ dataId?: string }
>(GET_MY_STUFF);
//... And then you can just call it when you need to
refetchIfNeeded({ dataId: "foo" });
打字稿在您的
中抱怨 useEffect(() => {
if (refetchNeeded) {
setRefetchNeeded(false);
refetch();
}
}, [refetchNeeded]);
refetch() says - Cannot invoke an object which is possibly 'undefined'.ts(2722)
const refetch: ((variables?: Partial<TVariables> | undefined) => Promise<ApolloQueryResult<TData>>) | undefined
and in [refetchNeeded] dependency -
React Hook useEffect 缺少依赖项:'refetch'。包含它或删除依赖项数组。eslintreact-hooks/exhaustive-deps const refetchNeeded:布尔值