代码之家  ›  专栏  ›  技术社区  ›  Shlomi Schwartz

反应Apollo:突变后存储更新,但ui不反映更改

  •  1
  • Shlomi Schwartz  · 技术社区  · 6 年前

    我创建了具有以下架构的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
      }
    }}`
    

    加载页面时,布局组件将所有图表显示为页面上的网格。用户以后可以添加新图表,因此我有两个变体:一个是创建图表,另一个是将新图表添加到布局中:

    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 条目已更新,但未反映在UI上,弹出的另一个条目是另一个名为 $ROOT_QUERY.layout({"id":"summary"}) 未使用新数据更新的:

    enter image description here

    我错过了什么?

    1 回复  |  直到 6 年前
        1
  •  3
  •   Daniel Rearden    6 年前

    From the docs :

    默认情况下,InMemoryCache将尝试使用id和\u id这两个常见主键作为唯一标识符(如果它们与对象上的\u typename一起存在)。

    如果未指定id和\u id,或者未指定\u typename,InMemoryCache将返回到查询中对象的路径,例如ROOT\u查询。所有人。0表示allPeople根查询上返回的第一条记录。这将使给定类型的数据在allPeople查询的范围内,而其他查询必须获取自己的单独对象。

    Apollo使用生成的密钥来确定当您的突变被解决时要更新什么。归根结底,您的查询和突变都需要包含id。这样,两者使用的生成密钥将是相同的。在您的代码中,看起来变异包含布局的id,但查询没有。

    如果由于某种原因,id不可用,可以使用 dataIdFromObject 用于标识要关闭的不同字段的选项。