Используйте apollo-link для получения запроса при любой мутации

#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»