Apollo Client中如何实现类似Relay的Prefetching数据预取?
Apollo Client 预取能力相关解答
Apollo Client 原生支持数据预取能力,完全可以实现你提到的、和Relay框架一致的交互效果:在用户按下触发跳转的按钮、手指尚未抬起时就提前发起数据请求,大幅降低页面加载等待感。
具体实现逻辑非常简单,不需要额外引入第三方依赖或者魔改源码:
- 核心利用Apollo Client全局暴露的
client.query()方法,你完全不需要等路由跳转完成、也不需要等目标页面组件挂载,只要监听到用户的pointerdown/touchstart/mousedown事件(也就是手指/鼠标按下还未抬起的时机),直接传入目标页面的查询语句和参数调用该方法即可,请求返回的数据会自动写入Apollo本地缓存。 - 等后续用户完成点击动作、真正跳转到目标页面时,页面内调用的
useQuery钩子会默认优先读取本地缓存,只要预取的请求已经返回,页面就可以直接用缓存数据渲染,做到近乎秒开的效果。
最小实现代码参考:
import { useApolloClient } from '@apollo/client'; function JumpButton({ detailPageQuery, detailId }) { const client = useApolloClient(); // 按下瞬间就触发预取,不等点击事件触发 const handlePointerDown = () => { client.query({ query: detailPageQuery, variables: { id: detailId }, fetchPolicy: 'cache-first' }) } // 点击完成(手指抬起)后再执行路由跳转 const handleClick = () => { // 这里替换成你项目用的路由跳转方法即可 history.push(`/detail/${detailId}`) } return ( <button onPointerDown={handlePointerDown} onClick={handleClick} > 查看详情 </button> ) }
几个实际使用的注意点:
- 相同query和参数的请求默认会命中缓存,不用担心用户反复按按钮触发重复请求、浪费流量的问题,你也可以通过配置缓存过期时间控制预取数据的有效期。
- 除了按钮按下的场景,列表滑动时预取可见项详情、鼠标hover导航项时预取对应页面数据这类场景,都可以用同样的逻辑实现,你可以完全自主控制预取的触发时机,灵活度比Relay的封装更高。
- 实际体验上和Relay的预取效果没有本质差异:Relay是把这套预取逻辑做了框架层的绑定封装,Apollo是把底层缓存和请求能力直接暴露,你可以根据自己的业务需求调整策略。
内容的提问来源于stack exchange,提问作者Vivienne Lee
相关产品推荐
相关产品推荐

