React Apollo中合并useQuery与useLazyQuery结果的实现方案
嘿,这个问题我太熟了!用Apollo Client的时候,这种同时用useQuery做初始加载、useLazyQuery做按需刷新的场景很常见,其实不用额外维护useState也能搞定,当然也有手动控制的方案,我给你拆解一下:
方案一:利用Apollo缓存自动同步(推荐)
Apollo Client的核心就是缓存管理,当你用同一个GET_POSTS_QUERY调用useQuery和useLazyQuery时,它们共享同一份缓存数据。也就是说,当你调用fetchPosts()触发按需查询后,Apollo会把新拿到的数据自动更新到缓存里,而useQuery返回的data会实时从缓存同步最新值——UI根本不需要管fetchedposts,直接用原来的data就会自动刷新!
举个实际代码例子:
import { useQuery, useLazyQuery } from '@apollo/client'; import GET_POSTS_QUERY from './queries/GetPosts'; function PostsList() { // 初始加载,直接用这个data渲染UI const { data } = useQuery(GET_POSTS_QUERY); // 按需加载的方法,这里甚至不需要解构data出来 const [fetchPosts] = useLazyQuery(GET_POSTS_QUERY); // 比如点击按钮刷新数据 const handleRefreshPosts = () => { // 如果需要强制从服务器拉取(忽略缓存),可以加fetchPolicy fetchPosts({ fetchPolicy: 'network-only' }); }; return ( <div> <button onClick={handleRefreshPosts}>刷新帖子</button> {data?.posts.map(post => ( <div key={post.id} className="post-item"> <h3>{post.title}</h3> <p>{post.content}</p> </div> ))} </div> ); }
这个方案最省心,完全利用Apollo的内置机制,不需要额外的状态管理,是大多数场景的首选。
方案二:手动用useState维护统一状态(适合特殊场景)
如果你有特殊需求——比如要对useLazyQuery返回的数据做预处理,或者不想依赖Apollo缓存的自动更新逻辑,那可以用useState来维护一个统一的渲染状态:
import { useQuery, useLazyQuery } from '@apollo/client'; import { useState, useEffect } from 'react'; import GET_POSTS_QUERY from './queries/GetPosts'; function PostsList() { const { data: initialPosts } = useQuery(GET_POSTS_QUERY); const [fetchPosts, { data: fetchedPosts }] = useLazyQuery(GET_POSTS_QUERY); // 用useState统一管理要渲染的帖子数据 const [posts, setPosts] = useState(initialPosts); // 监听fetchedPosts的变化,更新状态 useEffect(() => { if (fetchedPosts) { // 这里可以加数据处理逻辑,比如过滤、转换格式 setPosts(fetchedPosts); } }, [fetchedPosts]); const handleRefreshPosts = () => { fetchPosts(); }; return ( <div> <button onClick={handleRefreshPosts}>刷新帖子</button> {posts?.posts.map(post => ( <div key={post.id} className="post-item"> <h3>{post.title}</h3> <p>{post.content}</p> </div> ))} </div> ); }
这个方案更灵活,但需要自己处理状态同步,适合有自定义逻辑的场景。
总结一下
- 大多数情况直接用方案一,依赖Apollo缓存自动同步,代码简洁且符合Apollo的设计理念;
- 如果需要自定义数据处理或脱离缓存控制,再用方案二手动维护状态。
内容的提问来源于stack exchange,提问作者Rahul Bhooteshwar
相关产品推荐
相关产品推荐

