Состояние гонки локального кэша состояния Apollo-клиента?

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

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

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

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

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

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

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
0
1 036
1

Ответы 1

Такие методы, как 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>

Дополнительные сведения см. в статье документы.

Да, извините, я выразился неясно, на самом деле я использую writeQuery внутри мутации, хотя readQuery не используется внутри компонента запроса. Что лучше всего делать, если мне нужно получить доступ к кешу (будь то запись или чтение) вне метода рендеринга? Спасибо за Ваш ответ!

milanesa 24.01.2019 18:42

@milanesa Что ты пытаешься сделать? Вы можете использовать graphql HOC вместо компонента Query, но компонент Query является предпочтительным способом работы. Шаблон свойств рендеринга иногда заставляет вас реструктурировать ваши компоненты, но я совершенно уверен, что вы все равно можете использовать его для всего, что пытаетесь сделать. Было бы полезно, если бы вы отредактировали свой вопрос с соответствующим кодом и дополнительным объяснением того, чего вы на самом деле пытаетесь достичь.

Daniel Rearden 24.01.2019 18:49

Конечно, Даниэль, на самом деле я не могу загрузить код, но я пытаюсь сделать следующее. Я использую реагирующую навигацию на вкладке, где у меня есть реквизит, который сообщает, сфокусирован ли экран или нет, я хочу сохранить это значение, чтобы использовать его в другом компоненте, и после прочтения этого значения в этом компоненте мне нужно setState (что является плохой практикой внутри метода рендеринга). В другом случае мне нужно использовать его внутри HOC, который я создал. Спасибо!

milanesa 24.01.2019 18:58

FWIW, это не всегда возможно, но при публикации вопроса на SO полезно попытаться включить Минимальный, полный и проверяемый пример, даже если это не ваш реальный производственный код.

Daniel Rearden 24.01.2019 19:02

Я понимаю. Я не могу в этом случае, извините :( Спасибо за вашу помощь!

milanesa 24.01.2019 19:08

Другие вопросы по теме