You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 01:05:53