NextJS中能否用Apollo GraphQL缓存替代useState?是否会数据重复存储?
关于Apollo Client缓存与客户端数据处理的解答
核心结论
完全不需要用useState存储Apollo返回的data,直接基于Apollo的缓存数据做客户端筛选、排序等交互操作即可,这样能避免数据冗余,也更符合Apollo的设计逻辑。
具体实现方式
直接基于Apollo的data做客户端计算
useQuery返回的data本身就是从Apollo缓存中读取的(除非你手动配置了fetchPolicy跳过缓存),所以可以直接用这个数据结合React的useMemo来处理筛选逻辑,既避免冗余,还能缓存计算结果提升性能:
import { useQuery, gql } from '@apollo/client'; import { useState, useMemo } from 'react'; const GET_MOVIES = gql` query GetMovies{ movies{ id name genre yearReleased rating } } `; export default function MoviesPage() { const { data, loading, error } = useQuery(GET_MOVIES); // 只存筛选条件这类交互状态,不存完整的电影列表 const [selectedGenre, setSelectedGenre] = useState(''); // 基于Apollo返回的原始data做筛选,用useMemo缓存结果 const filteredMovies = useMemo(() => { if (!data?.movies) return []; return selectedGenre ? data.movies.filter(movie => movie.genre === selectedGenre) : data.movies; }, [data, selectedGenre]); if (loading) return <div>加载中...</div>; if (error) return <div>出错了:{error.message}</div>; return ( <div> <select value={selectedGenre} onChange={(e) => setSelectedGenre(e.target.value)} > <option value="">所有类型</option> <option value="动作">动作</option> <option value="喜剧">喜剧</option> </select> <ul> {filteredMovies.map(movie => ( <li key={movie.id}> {movie.name} - {movie.genre} ({movie.yearReleased}) </li> ))} </ul> </div> ); }
什么时候需要用useState存数据?
只有当你需要本地修改数据(未提交到服务器),或者需要维护一份和Apollo缓存完全独立的本地状态时,才需要用useState存储数据。比如你要做一个本地草稿编辑功能,暂时不想同步到后端,这时候可以把缓存的数据复制到useState里做修改。
关于Apollo缓存的补充
Apollo Client默认会自动缓存查询结果,后续相同的查询会优先从缓存读取,减少网络请求。如果需要强制刷新数据,可以调用useQuery返回的refetch方法,或者配置fetchPolicy: 'network-only'来绕过缓存。
内容的提问来源于stack exchange,提问作者Prabin Basnet
相关产品推荐
相关产品推荐

