首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >反应阿波罗:阿波罗-缓存-坚持似乎不起作用。

反应阿波罗:阿波罗-缓存-坚持似乎不起作用。
EN

Stack Overflow用户
提问于 2018-03-13 21:13:09
回答 2查看 2.5K关注 0票数 0

也许我误解了这个包的功能,但我认为它会读取缓存的响应并帮助实现离线应用程序功能。

代码语言:javascript
复制
import React from 'react'
import { graphql } from 'react-apollo'
import gql from 'graphql-tag'

export const DATA_QUERY = gql`
    query Data {
        me {
            name
            bestFriend {
                name
            }
        }
    }
`

const options = () => ({
  fetchPolicy: 'cache-only'
})

const withData = graphql(DATA_QUERY, { options })

export const Start = ({ data }) =>
    data.loading ? (
        'loading!'
    ) : data.me ? (
        <div>
      {console.log('data', data)}
            <h3>Me: {data.me.name}</h3>
            <p>Best friend: {data.me.bestFriend.name}</p>
        </div>
    ) : (
        'no data'
    )

export default withData(Start)

// index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';
import { ApolloProvider } from 'react-apollo'
import { ApolloClient } from 'apollo-client'
import { InMemoryCache } from 'apollo-cache-inmemory'
import { HttpLink } from 'apollo-link-http'
import { persistCache } from 'apollo-cache-persist'

const cache = new InMemoryCache()

persistCache({
  cache,
  storage: window.localStorage,
  debug: true
})

export const client = new ApolloClient({
  link: new HttpLink({ uri: 'https://v9zqq45l3.lp.gql.zone/graphql' }),
  cache
})

ReactDOM.render(
  <ApolloProvider client={client}>
    <App />
  </ApolloProvider>,
document.getElementById('root'));
registerServiceWorker();

我的localStorage中确实有缓存

代码语言:javascript
复制
apollo-cache-persist: "{"$ROOT_QUERY.me":{"name":"Bob","bestFriend":{"type":"id","id`enter code here`":"$ROOT_QUERY.me.bestFriend","generated":true}"

当使用fetchPolicy:‘缓存只’运行上面的示例时,组件呈现‘无数据’。如果我执行默认的fetchPolicy,缓存-首先,然后我得到了预期的结果,但我可以看到网络请求正在发出。

编辑:现在使用Daniels的答案,这个解决方法在运行查询之前等待恢复缓存。

代码语言:javascript
复制
import Start from './Start'

class App extends Component {
  state = {
    show: false
  }

  toggle = () =>
    this.setState({ show: !this.state.show })

  render() {
    return (
      <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <h1 className="App-title">Welcome to React</h1>
        </header>
        <br/><br/>
        <button onClick={this.toggle}>Show it</button>
        <br/><br/>
        {this.state.show && <Start />}
      </div>
    );
  }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-03-14 00:59:59

为了正确缓存并在以后从缓存中检索数据,阿波罗需要使用一个id (或_id)。如果希望使用不同的属性作为id (如name),则可以将dataIdFromObject函数传递给内存缓存的配置:

代码语言:javascript
复制
const cache = new InMemoryCache({
  dataIdFromObject: object => {
    switch (object.__typename) {
      //User is whatever type "me" query resolves to
      case 'User': return object.name;
      default: return object.id || object._id;
    }
  }
});
票数 1
EN

Stack Overflow用户

发布于 2018-03-14 17:22:36

像这样的东西可以工作,但我想知道是否应该有一个更优雅的解决方案。也许是重试链接。

https://github.com/apollographql/apollo-cache-persist/issues?utf8=%E2%9C%93&q=is%3Aissue+

代码语言:javascript
复制
export class Index extends Component {
    state = {
        client: null
    }

    async componentWillMount() {
        const httpLink = new HttpLink({ uri: 'https://v9zqq45l3.lp.gql.zone/graphql' })

        const link = ApolloLink.from([ httpLink ])

        const cache = new InMemoryCache({
            dataIdFromObject: (object) => {
                switch (object.__typename) {
                    // User is whatever type "me" query resolves to
                    case 'User':
                        return object.name
                    default:
                        return object.id || object._id
                }
            }
        })

        await persistCache({
            cache,
            storage: window.localStorage,
            debug: true
        })

        const client = new ApolloClient({
            link,
            cache
    })

    this.setState({ client })
    }

    render() {
        return !this.state.client ? (
            null
        ) : (
            <ApolloProvider client={this.state.client}>
                <App />
            </ApolloProvider>
        )
    }
}

ReactDOM.render(<Index />, document.getElementById('root'))
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49265959

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档