#reactjs #graphql #react-apollo #apollo-client #apollo-link
#reactjs #graphql #реагировать-apollo #apollo-client #apollo-link
Вопрос:
Я работаю над приложением, в котором есть проекты с вложенным деревом активов. В серверной части дата изменения проекта обновляется при обновлении одного из дочерних элементов внуков (или внуков-внуков).
В react-apollo я настроил все запросы таким образом, что обновленный объект возвращается, а кэш apollo обновляется обновленными данными. Но я также хотел бы обновить измененную дату проекта (который может быть родительским, дедушкиным и т. Д.).
Одним из решений является использование опции refetchQueries . Однако это означало бы, что мне нужно реализовать эту опцию refetchQueries во всех частях, где используется перехват useMutation, что приводит к большому дублированию кода плюс риск того, что он может быть забыт другими разработчиками (командой из 4 человек). Лучшим вариантом является создание пользовательского хука, который оборачивает хук useMutation, но разработчикам все равно нужно его использовать.
Поэтому сейчас я рассматриваю возможность использования apollo-link для этого, что повлияет на все выполненные мутации. Однако я не могу понять, можно ли добавить запрос к операции или поставить запрос в очередь, и если возможно — как это сделать?
Спасибо за вашу помощь!
Ответ №1:
Используя ApolloLink, вы можете генерировать ссылки afterware
для анализа возвращенных ответов и условно обновлять кеш в соответствующих случаях.
import { ApolloLink } from "apollo-link";
import { createHttpLink } from "apollo-link-http";
const httpLink = createHttpLink({ uri: "/graphql" });
const updateDateCacheLink = new ApolloLink((operation, forward) => {
return forward(operation).map(response => {
const context = operation.getContext();
const { response: { headers } } = context;
/* conditionally update cache */
return response;
});
});
// use with apollo-client
const link = updateDateCacheLink.concat(httpLink);
В качестве альтернативы вы можете рассмотреть возможность использования HOC, возвращающего компонент, который реализует update
обратный useMutation
вызов , который получает полезную нагрузку обновления. Это позволило бы избежать дублирования и инкапсулировать общую логику кэширования, соответствующую вашему запросу. И, как вы заметили, пользовательский хук может быть обернут и использоваться вместо useMutation (не показано ниже).
const withMutationCacheUpdate = args => Wrapped => {
return function(props) {
const [updateData] = useMutation(UPDATE_DATA, {
update(cache, { data: { newData } }) {
// Read relevant data from cache with cache.readQuery,
// then update using cache.writeQuery, cache.writeFragment
// or cache.modify as appropriate with returned payload and possibly args
},
})
return <Wrapped {...props} updateData={updateData} />
}
}
const config = {...}
const YourComponent = props => { ... }
const YourWrappedComponent = withMutationCacheUpdate(config)(YourComponent)
Комментарии:
1. Спасибо за ваш ответ! Однако я надеялся, что можно было бы фактически добавить еще один запрос (т. Е. «запрос { проекты { изменено } }») всякий раз, когда производится мутация. Так что возвращаемый ответ на самом деле больше, чем указано в запросе мутации. Но я считаю, что это невозможно, после многих поисков в Интернете. Итак, теперь я предоставил новый пользовательский хук, который всегда выполняет дополнительный запрос, используя опцию «refetchQueries». Мы будем использовать этот пользовательский хук в качестве замены «useMutation»