如何从apollo缓存中获取最新数据[英] How to get updated data from apollo cache

本文是小编为大家收集整理的关于如何从apollo缓存中获取最新数据的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

Apollo客户端是否有某种东西,例如mapStateToProps(redux)?

假设我有一个组件,查询后,我知道缓存中有数据,所以我做类似的事情:

    class Container extends React.Component {
      ...
      ...
      render() {
        const notes = this.props.client.readFragment(NOTES_FRAGMENT)
        // notes has everything I need
        return (<Child notes={notes} />);
      }

    }
    export default WithApollo(Container);

但是,当我有一个调用突变并进行更新的兄弟姐妹组件时,<Child />组件的道具永远不会得到更新.

class AnotherContainer extends React.Component {
   render() {
     return(
       <Mutation
          mutation={UPDATE_NOTE}
          update={(cache, {data: {updateNote}}) =? {
            const list = cache.readFragment({
              fragment: NOTES_FRAGMENT
            })
            // manipulate list
            cache.writeFragment({fragment:NOTES_FRAGMENT, data })
          }
        }
     )
   }
}

所以我的问题是,每当我写fragment时,如何更新<Child />组件的道具?是否有像MapStateToprops之类的东西可以将notes道具"连接"到缓存,因此,每当它更新时,都会触发React Lifececle?

推荐答案

react-apollo提供了三种方法,可以收听缓存中的更改:1)查询组件,2) graphql hoc 和3)直接使用客户端调用watchQuery.在所有三种情况下,您都提供一些查询和任何适当的选项,并且您可以将最初获取该查询并收听更新的方法.

这里的关键是查询,而不是片段是阅读缓存的预期车辆. readFragment方法仅是作为一种方便的方式来读取一个时间(通常是在突变后更改缓存的背景下),并且不提供任何反应性.

so,底线,将组件包装在Query组件或graphql hoc中,您将可以访问反映查询结果的道具,并在缓存更新时进行更新(相同(相同) Way connect ED组件做).

在这一点

"但是我不需要提出另一个服务器请求!" 不用担心 - 默认情况下,阿波罗只会要求相同的查询一次,并且将使用缓存用于所有后续调用.您可以通过设置适当的 rel="noreferrer"> rel="noreferrer"> noreferrer">获取策略您的查询.这包括cache-only策略,该策略只会从缓存中获取数据(尽管默认cache-first策略对于大多数用例就足够).

"但是我没有查询! a href =" https://github.com/apollographql/apollo-link-state" rel =" noreferrer"> apollo-link-state 这样做.

"但是我不需要整个查询结果,只是其中的一部分!您将查询数据转换为要使用的任何形状.将渲染道具模式与Query组件一起使用时,实际上并不需要相同的功能 - 您可以直接操纵渲染道具.无论哪种情况,最好编写一些还原器,您可以在整个项目中重复使用这些简化器,这些简化器只需将返回的数据转换为所需的形状即可.我从事的最后一个大型项目只是做了那个客户方面,它使事情更易于管理.

本文地址:https://www.itbaoku.cn/post/1938064.html

问题描述

Does Apollo client have some sort of thing like mapStateToProps (Redux)?

let's say I have a component, after query I know there's data in the cache so I do something like:

    class Container extends React.Component {
      ...
      ...
      render() {
        const notes = this.props.client.readFragment(NOTES_FRAGMENT)
        // notes has everything I need
        return (<Child notes={notes} />);
      }

    }
    export default WithApollo(Container);

However when I have a sibling component which calls mutation and do update, the <Child /> component's props never get updates.

class AnotherContainer extends React.Component {
   render() {
     return(
       <Mutation
          mutation={UPDATE_NOTE}
          update={(cache, {data: {updateNote}}) =? {
            const list = cache.readFragment({
              fragment: NOTES_FRAGMENT
            })
            // manipulate list
            cache.writeFragment({fragment:NOTES_FRAGMENT, data })
          }
        }
     )
   }
}

so my question is, how do I update the <Child /> component's props whenever I do writeFragment? is there anything like mapStateToProps thing to "connect" the notes props to the cache, so whenever it updates, will trigger the React lifecycle?

推荐答案

react-apollo provides three ways you can listen for changes in the cache: 1) the Query component, 2) the graphql HOC, and 3) calling watchQuery directly using the client. In all three cases, you provide some query and any appropriate options, and you get a way to initially fetch that query as well as listen to updates to it.

The key here is that queries, and not fragments are the intended vehicles for reading the cache. The readFragment method is only meant as a convenient way to read the cache a single time (usually in the context of changing the cache after a mutation) and does not provide any sort of reactivity.

So, bottom line, wrap your components in either the Query component or the graphql HOC and you will have access to props that reflect the query results in the cache and that will update when the cache updates (the same way connected components do).

At this point a couple of things might be going through your head:

"But I don't need to make another server request!" No worries -- by default, Apollo will only request the same query once, and will use the cache for all subsequent calls. You can modify this behavior by setting the appropriate fetch policy for your query. This includes a cache-only policy that will only pull data from cache (although the default cache-first policy is sufficient for most use cases).

"But I don't have a query to work with!" If you're writing to the cache as a means of persisting some arbitrary client-side state, then you should be using apollo-link-state to do so.

"But I don't need the entire query result, just a part of it!" The graphql HOC provides a props function you can pass in to the configuration that will let you transform your query data into whatever shape you want to work with. The same functionality isn't really needed when using the render props pattern with the Query component -- you can just manipulate the render props directly. In either case, it may be a good idea to write some reducers that you can reuse throughout your project that just take the returned data and transform it into the shape you need. The last big project I worked on did just that client side and it kept things much more manageable.