javascript - Apollo 客户端本地状态缓存竞争条件?

标签 javascript reactjs graphql apollo apollo-client

因此,我一直尝试在 React 应用程序中使用 apollo-boost 来使用缓存来管理我的客户端状态,在查询中使用 @client 指令,但我遇到了一些问题。

基本上,我使用 writeQuery() 将 bool 值写入组件(我们称之为组件 A)中的本地应用程序状态,并希望使用 readQuery() 在另一个组件(我们称之为组件 B)中获取该值在 componentDidUpdate 方法内。问题是,组件 B 中的 readQuery() 在组件 A 中的 writeQuery 设置缓存/本地状态中的值之前运行,因此组件 B 读取的值是错误的。

我已经通过使用 setTimeout 延迟 readQuery() 来确认这一点,并且确实在使用超时后,该值是正确的,但是这个解决方案不可信,我可能不知道 Apollo 客户端中的某些内容,因为这个功能对于本地状态管理来说是非常基本的。有什么建议吗?

我相信在 Redux 中这个问题已经解决了,因为状态被注入(inject)到 props 中,这使得组件更新,因此组件 A 是改变状态的组件,组件 B 甚至不必使用 componentDidUpdate 来获取新值,因为状态将被注入(inject)并且组件 B 将使用正确的值进行更新。

任何帮助将不胜感激,抱歉,如果我没有说清楚!

编辑: writeQuery() 正在 Mutation 解析器内部使用。

最佳答案

诸如 readQuerywriteQuery 之类的方法旨在用于读取和修改突变内部的缓存。一般来说,它们不应该直接在组件内部使用。通过调用readQuery,您只需从缓存中获取数据一次。相反,您应该使用查询组件。

const TODO_QUERY = gql`
  query GetTodos {
    todos @client {
      id
      text
      completed
    }
  }
`

<Query query={TODO_QUERY}>
  {({ data }) => {
    if (data.todos) return <ToDoListComponent todos={data.todos}/>
    return null
  }}
</Query>

Query 组件订阅缓存的相关更改,因此 data 的值将在缓存更新时更新。

同样,您应该为要对缓存进行的任何更改创建适当的突变,然后利用 Mutation 组件来实际突变缓存。

const client = new ApolloClient({
  clientState: {
    defaults: {
      todos: []
    },
    resolvers: {
      Mutation: {
        addTodo: (_, { text }, { cache }) => {
          const previous = cache.readQuery({ query: TODO_QUERY })
          const newTodo = { id: nextTodoId++, text, completed: false, __typename: 'TodoItem' }
          const data = {
            todos: previous.todos.concat([newTodo]),
          }

          cache.writeQuery({ query, data })
          return newTodo
        },
      },
    }
  }
})

<Mutation mutation={ADD_TODO}>
  {(addTodo) => (
    // use addTodo to mutate the cache asynchronously
  )}
</Mutation>

请查看the docs了解更多详情。

关于javascript - Apollo 客户端本地状态缓存竞争条件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54349855/

相关文章:

javascript - 立即调用函数表达式 (IIFE) 与非立即调用函数表达式

javascript - 跨 Controller 共享和观察数据

reactjs - 如何在reactstrap Dropdown中设置所选项目?

GraphQL:返回 null 与抛出错误

javascript - 巴别塔 7 : Uncaught ReferenceError after transpiling a module

javascript - jQuery 切换设置显示为与初始设置不同的值

reactjs - 自定义 React Router 渲染顺序

javascript - React 组件中的 handleScroll 值

github - 使用 GraphQL 突变删除 github 中的一个分支

javascript - 如何查询动态数量的别名?