React Apollo: сохранять обновления после мутации, но пользовательский интерфейс не отражает изменения

Я создал сервер graphQL со следующей схемой:

...
#charts interface
interface Chart {
  id: String!
  sql: String!
  title: String
  type: String!
  display: String!
}
type Layout{
  # Unique layout id
  id: String
  # The title displayed on the layout tab
  title: String
  # List of displayed charts
  charts: [Chart]
}
...

На моем клиенте у меня есть компонент <SummaryLayout/> со следующим запросом gql:

gql`{
layout(id:"summary"){
  title
  charts {
    id,
    title,
    type,
    display
  }
}}`

При загрузке страницы компонент макета отображает все диаграммы в виде сетки на странице. Позже пользователь может добавить новую диаграмму, поэтому у меня есть 2 мутации: одна создает диаграмму, а другая добавляет новую диаграмму в макет:

const addToLayout = gql`
mutation addToLayout($layoutID: String!, $chartID: String!) {
  addToLayout(layoutID: $layoutID ,chartID:$chartID){
    id
    charts {
      id
      sql
      title
      type
      display
    }
  }
}`;

const addChart = gql`
mutation addChart($chartConfig:ChartConfig!) {
  addChart(chartConfig:$chartConfig){
    id
    display
  }
}`;

this.props.addChart({
    variables: {chartConfig: chartConfig}
    }).then((response) => {
       const chartID = response.data.addChart.id;
       console.log("Chart added, DB ID:", chartID);
       this.props.addToLayout({
            variables: {layoutID: "summary", chartID: chartID},
            update: (store, data) => {
              console.log("STORE:",store);
            }
          }).then((response) => {
            appState.toggleDialog(false);
          })
     });

Когда я регистрируюсь в магазине, я вижу, что запись Layout:summary обновляется, но это не отражается в пользовательском интерфейсе, еще одна вещь, которая всплывает, заключается в том, что есть еще одна запись с именем $ROOT_QUERY.layout({"id":"summary"}), которая не обновляется новыми данными:

введите здесь описание изображения

Что мне не хватает?


person Shlomi Schwartz    schedule 22.02.2018    source источник


Ответы (1)


Из документации:

По умолчанию InMemoryCache попытается использовать часто встречающиеся первичные ключи id и _id для уникального идентификатора, если они существуют вместе с __typename в объекте.

Если id и _id не указаны или если не указано __typename, InMemoryCache будет использовать путь к объекту в запросе, например ROOT_QUERY.allPeople.0 для первой записи, возвращаемой корневым запросом allPeople. Это сделало бы данные для данного типа доступными для запроса allPeople, а другим запросам пришлось бы извлекать свои собственные отдельные объекты.

Apollo использует этот сгенерированный ключ, чтобы определить, что нужно обновить, когда ваша мутация будет разрешена. Все сводится к тому, что и ваши запросы, и мутации должны включать идентификатор. Таким образом, сгенерированный ключ, используемый обоими, будет одинаковым. В вашем коде похоже, что мутация включает идентификатор макета, а запрос - нет.

Если по какой-то причине идентификатор недоступен, вы можете использовать параметр dataIdFromObject, чтобы указать другое поле, от которого нужно отказаться.

person Daniel Rearden    schedule 23.02.2018
comment
Спасибо проверю, думал id в свойствах хватит. - person Shlomi Schwartz; 24.02.2018
comment
Идеальный! это было то, чего мне не хватало - person Shlomi Schwartz; 25.02.2018