来自 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 有默认的fetchPolicycache-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:在订阅更新时更新 React 道具?

Apollo GraphQL (React) 跨组件数据共享

如何在 react-apollo graphql 查询中正确使用动态变量?

React Apollo 和 Redux:将自定义 reducer 与 Apollo 状态相结合

@apollo/react-hooks 中的 `useSubscription` 方法加载卡住

为啥在 React 中的 Apollo 客户端中显示错误未显示