Итак, я пытался использовать apollo-boost в приложении React, чтобы использовать кеш для управления состоянием моего клиента с помощью директив @client в запросах, но у меня возникли некоторые проблемы.
В основном я использую writeQuery() для записи логического значения в состояние моего локального приложения в компоненте (назовем его компонентом A) и хочу получить это значение в другом компоненте (назовем его компонентом B), используя readQuery() внутри componentDidUpdate метод. Дело в том, что readQuery() в компоненте B запускается до того, как writeQuery в компоненте A устанавливает значение в кэше/локальном состоянии, поэтому значение, считанное компонентом B, оказывается неверным.
Я подтвердил это, используя setTimeout для задержки readQuery(), и действительно, после использования тайм-аута значение правильное, но этому решению нельзя доверять, я, вероятно, не знаю чего-то в Apollo Client, потому что эта функция довольно простой для местного государственного управления. Какие-нибудь советы?
Я считаю, что в Redux это решено, потому что состояние вводится в реквизит, что приводит к обновлению компонента, поэтому, поскольку компонент A изменяет состояние, компоненту B даже не нужно использовать componentDidUpdate для получения нового значение, так как состояние будет введено, и компонент B будет обновлен с правильным значением.
Любая помощь будет оценена по достоинству, извините, если я не ясно выразился!
Обновлено: writeQuery() используется внутри преобразователя мутаций.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Такие методы, как 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>
Дополнительные сведения см. в статье документы.
@milanesa Что ты пытаешься сделать? Вы можете использовать graphql HOC вместо компонента Query, но компонент Query является предпочтительным способом работы. Шаблон свойств рендеринга иногда заставляет вас реструктурировать ваши компоненты, но я совершенно уверен, что вы все равно можете использовать его для всего, что пытаетесь сделать. Было бы полезно, если бы вы отредактировали свой вопрос с соответствующим кодом и дополнительным объяснением того, чего вы на самом деле пытаетесь достичь.
Конечно, Даниэль, на самом деле я не могу загрузить код, но я пытаюсь сделать следующее. Я использую реагирующую навигацию на вкладке, где у меня есть реквизит, который сообщает, сфокусирован ли экран или нет, я хочу сохранить это значение, чтобы использовать его в другом компоненте, и после прочтения этого значения в этом компоненте мне нужно setState (что является плохой практикой внутри метода рендеринга). В другом случае мне нужно использовать его внутри HOC, который я создал. Спасибо!
FWIW, это не всегда возможно, но при публикации вопроса на SO полезно попытаться включить Минимальный, полный и проверяемый пример, даже если это не ваш реальный производственный код.
Я понимаю. Я не могу в этом случае, извините :( Спасибо за вашу помощь!
Да, извините, я выразился неясно, на самом деле я использую writeQuery внутри мутации, хотя readQuery не используется внутри компонента запроса. Что лучше всего делать, если мне нужно получить доступ к кешу (будь то запись или чтение) вне метода рендеринга? Спасибо за Ваш ответ!