【问题标题】:Getting Count of Cached Data Without Hitting Server在不访问服务器的情况下获取缓存数据的计数
【发布时间】:2018-09-09 21:50:39
【问题描述】:

假设我有以下 React 组件:

import { Query } from 'react-apollo'

const MovieListContainer = () => (
  <Query query={QUERY}>
    {
      ({ loading, error, data }) => {
        if (loading) return (<p>Loading...</p>)
        if (error && !data) return (<p>Error...</p>)
        return <MovieList movies={ data.movies }
      }
    }
  </Query>
)

本质上,这用于从 GraphQL 缓存中获取电影列表(必要时访问服务器)以显示。我想尽量减少用户看到“正在加载”屏幕的时间,所以在初始化我的应用程序时我可能会这样做:

import { MOVIE_QUERY } from './queries'

const client = new ApolloClient({
  uri: 'http://example.com:3000/graphql'
})
// Query the movies immediately, and refresh every 30 seconds
client.query({ query: MOVIE_QUERY })
client.watchQuery({query: MOVIE_QUERY }, pollInterval: 30000)

const App = () => (
  <ApolloProvider client={client}>
    <Layout />
  </ApolloProvider>
)

这很好用。问题是,现在假设我想制作另一个组件来显示列表中的电影数量....

const MovieTab = ({ count }) => {
  <Tab>
    <span>Movies</span>
    <Badge>{ count }</Badge>
  </Tab>
}

如何创建一个容器来将MovieTab 连接到 Apollo 缓存以获取电影列表而不会导致数据库命中(如果需要,在徽章中显示“??”)?我尝试过的一些事情:

  • 将其包装在Query 中,其中查询类似于movies { id }。我已将此作为答案发布,但我仍然对此并不着迷。
  • 将其包装在Query 中,其中查询为MOVIE_QUERY。似乎与使用 GraphQL 仅获取所需数据的想法背道而驰。
  • 将其包装在 ApolloConsumer 中以访问客户端,然后调用 readQuery 以获取电影列表。这保证了我不会访问数据库,但在缓存实际填满数据之前不会工作。

【问题讨论】:

    标签: javascript react-apollo apollo-client


    【解决方案1】:

    这是我目前的做法:

    const QUERY = gql`
    movies { id }
    `
    
    const MovieTabContainer = () => (
      <Query query={ QUERY } fetchPolicy='cache-only'>
        ({ data }) => {
          const count = data.movies ? data.movies.length : '??'
          return (
            <MovieTab count={ count } />
          )
        }
      </Query>
    )
    

    通过指定获取策略为仅缓存,我们将立即传递data(这将是一个空对象)。我们可以将此视为我们还不知道计数的标志。通过执行完整的电影查询填充缓存后,MovieTab 组件将被重新渲染以包含实际长度。

    【讨论】:

      【解决方案2】:

      如果查询已经在其他地方获取,我认为使用MOVIE_QUERYcache-only 是一个很好且简单的解决方法。假设您没有访问公共 API,或者至少可以对 API 的设计方式进行一些控制,那么这里最简洁的解决方案实际上可能是服务器端解决方案。

      而不是像这样构建架构:

      type Query {
        movies: [Movies!]!
      }
      

      您可以改为混合一些元数据,至少是这样的:

      type Query {
        movies: QueryResult
      }
      
      type QueryResult {
        total: Int
        items: [QueryItem!]!
      }
      
      union QueryItem = Movie | Actor | Director
      

      这可以让您直接查询缓存的总数。

      【讨论】:

        猜你喜欢
        • 2021-09-08
        • 1970-01-01
        • 2015-12-18
        • 1970-01-01
        • 2011-01-21
        • 2018-09-09
        • 2014-07-20
        • 2012-11-17
        • 1970-01-01
        相关资源
        最近更新 更多