Как обновить кеш Apollo после запроса? - PullRequest
2 голосов
/ 25 января 2020

Как я могу переопределить значение в кэше Apollo?

У меня есть запрос graphql для извлечения пользователя. Это возвращает пользователя с валютой по умолчанию. Затем эту валюту можно переопределить из выпадающего списка.

Запрос извлекает paymentCurrencies из API, затем использует распознаватель на стороне клиента, чтобы установить первый элемент в массиве paymentCurrencies для пользователей currency

query me {
  me {
    username
    currency @client
    paymentCurrencies
  }
}

Когда кто-то выбирает валюту из выпадающего меню, я хочу перевести валюту пользователя на то, что он выбрал.

Пока у меня есть что-то вроде этого:

const onChange = e => {
  const { value } = e.target
  client.writeData({ user: { currency: value, username, __typename: "User" } })
}

Я получаю следующее ошибка: Error writing result to store for query: {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GeneratedClientQuery"},"selectionSet":null}]} Cannot read property 'selections' of null

Использует ли writeData правильный метод или я должен использовать writeQuery или что-то еще?

Ответы [ 3 ]

1 голос
/ 25 января 2020

Как описано в другом ответе, вы, вероятно, хотите простой запрос и настройку мутации. Директива client используется для расширения вашей схемы для хранения дополнительных данных только для клиента. Из вашего объяснения кажется, что вы явно хотите, чтобы эти данные были синхронизированы с сервером.

const ME_QUERY = gql`
  query me {
    me {
      username
      currency
      paymentCurrencies
    }
  }
`;

const CURRENCY_MUTATION = gql`
  mutation setCurrency($currency: String) {
    setCurrency(currency: $currency) {
      me {
        username
        currency
      }
    }
  }
`;

function MyComponent() {
  const { data } = useQuery(ME_QUERY);
  const [setCurrency] = useMutation(CURRENCY_MUTATION);

  const onChange = e => setCurrency({
    variables: { currency: e.currentTarget.value },
  });

  return (
    <>
      <h2>{data && data.me.currency}</h2>
      <select onChange={onChange}>
        {/* your dropdown logic */}
      </select>
    </>
  );
}

Вы поняли идею. Apollo теперь будет автоматически обновлять ваш кеш. Убедитесь, что ваша мутация позволяет запрашивать обновленный объект пользователя.

Для автоматического обновления c на работу ваш пользователь должен быть распознан в кеше . Это можно сделать, либо добавив поле id и выбрав его как в запросе, так и в мутации, либо реализовав функцию dataIdFromObject в Apollo Client 2.x, которая включает имя пользователя для __typename === 'User', или используя политику типов в Apollo Client. 3.x. Найдите документы здесь .

1 голос
/ 25 января 2020

writeData следует использовать для изменения полей в root, например:

{
  yourState @client
}

В этом случае вам следует использовать writeQuery. Кроме того, этот лог c действительно должен быть извлечен в (локальную) мутацию, которую вы затем можете вызвать внутри своего компонента. При использовании writeQuery основная идея c заключается в том, чтобы захватить существующие данные, сделать копию и затем преобразовать их по мере необходимости:

const { me } = client.readQuery({ query: ME_QUERY })
const data = {
  me: {
    ...me,
    currency: value,
  }
}
client.writeQuery({ query: ME_QUERY, data })

Вы также можете использовать writeFragment для непосредственного изменения одного экземпляр объекта в кеше. Однако для этого вам нужен ключ кеша объекта. Поскольку ключ кеша получен из __typename и поля id, вы должны убедиться, что запрос сначала содержит поле id . Это хорошая практика, несмотря на то, что ваш кэш может быть легко обновлен (см. здесь для более подробной информации). Тогда вы можете сделать что-то вроде этого:

client.writeFragment({
  id: 'User:42',
  fragment: gql`
    fragment UserCurrency on User {
      currency @client
    }
  `,
  data: {
    currency: value,
  },
})
0 голосов
/ 25 января 2020

Это зависит.

Для постоянных изменений (syn c на сервер) вы должны просто изменить настройки пользователя с помощью мутации.

Для изменений с учетом сессий - не использовать настройки пользователя - скопируйте это (из свойств зарегистрированного пользователя) в отдельное значение в глобальном состоянии приложения (redux / mobx или как в этом случае apollo local state ).

В обоих случаях редкая проблема может быть связана с обновлением многих компонентов с использованием измененных данных.

Redux / mobx решает это автоматически.
Apollo HOC не будет перерисовываться.
Hooks - обновления частично (только один с парой useQuery и useMutation), другие будут обновляться только при повторной визуализации.
Компоненты, созданные с помощью <Query/>, создают внутреннюю наблюдаемую информацию, затем они также обновляются.

Мутация имеет update и refetchQueries параметры для. Существует также пакет для более сложных вариантов использования.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...