来自 apollo react 的 useQuery 方法的意外结果
Posted
技术标签:
【中文标题】来自 apollo react 的 useQuery 方法的意外结果【英文标题】:Unexpected result from apollo react's useQuery method 【发布时间】:2021-08-26 10:59:23 【问题描述】:对于一个项目,我通过在上下文中运行 AuthenticationProvider
内的 GraphQL 查询来实现身份验证,我注意到该查询两次获取数据。
const AuthenticationProvider: FC = props =>
const
loading,
data
= useQuery(MeQuery)
if (loading) return null
return <AuthenticationContext.Provider value=user: data?.me || null ...props />
尽管查询运行完美,但我仍然想知道为什么它会两次获取数据。我做了一些谷歌搜索,遇到了这个问题,其中提供了this answer。我尝试了同样的事情,使用 skip
选项,基于数据是否加载。
const [skip, setSkip] = useState(false)
const
loading,
data
= useQuery(MeQuery, skip )
useEffect(() =>
if (!loading && data?.me)
setSkip(true)
, [loading, data])
// ...
但是登录后就停止工作了。
const useLoginMutation = () => useMutation(LOGIN_QUERY, update: (cache, data ) =>
if (!data)
return null
cache.writeQuery( query: MeQuery, data: me: data.login )
)
缓存仍然使用正确的值更新,但不再检索用户(null)。
const user = useContext(AuthenticationContext)
我在这里缺少什么?查询似乎确实运行并获取了正确的数据。
【问题讨论】:
【参考方案1】:使用 apollo useQuery 时不需要使用上下文。如果您先进行查询,则提取的数据将存储在缓存中。您可以在运行查询的第二秒内直接访问缓存中的数据。因为 useQuery 有默认的fetchPolicy
cache-first
。如果在发出网络请求之前没有进行任何查询,则意味着它首先检查缓存。
如果您想避免网络加载。你可以制作一个***组件AuthWrapper
。
const useUserQuery = () => useQuery(ME_QUERY);
const AuthWrapper = (children) =>
const loading, data = useUserQuery();
if(loading) return null
return children;
export GetUsetInThisComponent = () =>
// Since we have fetched the user in AuthWrapper, the user will be fetched from the cache.
const data = useUserQuery();
// No you can access user from data?.user
// Rest of the application logic
// Wrap the component like this to avoid loading in the children components
<AuthWrapper>
<GetUserInThisComponent />
</AuthWrapper>
【讨论】:
是不是要查询更多上下文的原因?以上是关于来自 apollo react 的 useQuery 方法的意外结果的主要内容,如果未能解决你的问题,请参考以下文章
Apollo GraphQL (React) 跨组件数据共享
如何在 react-apollo graphql 查询中正确使用动态变量?
React Apollo 和 Redux:将自定义 reducer 与 Apollo 状态相结合