Apollo-клиент локальное состояние кэш гонки? - PullRequest
0 голосов
/ 24 января 2019

Поэтому я пытался использовать apollo-boost в приложении React, чтобы использовать кэш для управления состоянием моего клиента с помощью директив @client для запросов, но у меня возникли некоторые проблемы.

В основном я использую writeQuery (), чтобы записать логическое значение для моего локального состояния приложения в компоненте (назовем его компонентом A), и хочу получить это значение в другом компоненте (назовем его компонентом B), используя readQuery () внутри метода componentDidUpdate. Дело в том, что readQuery () в Компоненте B выполняется до того, как writeQuery в Компоненте A устанавливает значение в кеше / локальном состоянии, поэтому значение, прочитанное Компонентом B, получается неверным.

Я подтвердил это с помощью setTimeout, чтобы задержать readQuery (), и действительно после использования тайм-аута значение верное, но этому решению нельзя доверять, я, вероятно, не знаю что-то в клиенте Apollo, потому что эта функциональность довольно проста для местного государственного управления. Любые советы?

Я полагаю, что в Redux это решается, потому что состояние вводится в реквизиты, что приводит к обновлению компонента, поэтому, так как компонент A является тем, который изменяет состояние, компонент B даже не должен будет использовать componentDidUpdate для получить новое значение, так как состояние будет введено, и компонент B будет обновлен с правильным значением.

Буду признателен за любую помощь, извините, если я не прояснился!

EDIT: writeQuery () используется внутри распознавателя мутаций.

1 Ответ

0 голосов
/ 24 января 2019

Методы типа readQuery и writeQuery предназначены для чтения и изменения кеша внутри мутаций. Как правило, они не должны использоваться внутри компонентов напрямую. Вызывая readQuery, вы извлекаете данные из кэша только один раз. Вместо этого вы должны использовать Query компонент.

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>

Пожалуйста, просмотрите документы для более подробной информации.

...