Javascript React Apollo:当两个组件同时呈现时,无法读取未定义的属性

Javascript React Apollo:当两个组件同时呈现时,无法读取未定义的属性,javascript,reactjs,graphql,react-apollo,apollo-client,Javascript,Reactjs,Graphql,React Apollo,Apollo Client,我遇到了一个有关react apollo包的问题: 我有两个组件查询相同的graphql对象 每个组件都独立工作,没有错误 当我同时渲染两者时,我得到undefined错误的无法读取属性 我能够用这个演示代码重新创建错误。请在此处以及下面查找: 我所做的尝试没有成功 使用会导致完全相同的行为 使用did可以工作,但对于我的现实世界用例来说是不可接受的,因为出于性能原因,这两个组件需要使用缓存 使用did可以工作,但对于我的真实世界用例来说是不可接受的,因为这会降低每个页面上两个组件的速度

我遇到了一个有关
react apollo
包的问题:

  • 我有两个组件查询相同的graphql对象
  • 每个组件都独立工作,没有错误
  • 当我同时渲染两者时,我得到undefined错误的
    无法读取属性
我能够用这个演示代码重新创建错误。请在此处以及下面查找:

我所做的尝试没有成功
  • 使用会导致完全相同的行为
  • 使用did可以工作,但对于我的现实世界用例来说是不可接受的,因为出于性能原因,这两个组件需要使用缓存
  • 使用did可以工作,但对于我的真实世界用例来说是不可接受的,因为这会降低每个页面上两个组件的速度
仅在渲染两个组件时发生的错误 PlanetPhysics.js

import React from "react";
import gql from "graphql-tag";
import { Query } from "react-apollo";
import { DataBlock } from "./DataBlock";

const PHYSICS_QUERY = gql`
  query {
    allPlanets(first: 4) {
      planets {
        id
        name
        diameter
        rotationPeriod
      }
    }
  }
`;

export function PlanetPhysics() {
  return (
    <Query query={PHYSICS_QUERY}>
      {({ loading, error, data }) => {
        if (loading) return "Loading...";
        if (error) return `Error! ${error.message}`;
        return (
          <div>
            {data.allPlanets.planets.map(p => (
              <DataBlock data={p} title={`Physics: ${p.name}`} key={p.id} />
            ))}
          </div>
        );
      }}
    </Query>
  );
}
从“React”导入React;
从“graphql标签”导入gql;
从“react apollo”导入{Query};
从“/DataBlock”导入{DataBlock};
常量物理\u查询=gql`
质疑{
所有行星(第一:4){
行星{
身份证件
名称
直径
旋转周期
}
}
}
`;
导出功能PlanetPhysics(){
返回(
{({加载,错误,数据})=>{
如果(加载)返回“加载…”;
if(error)返回`error!${error.message}`;
返回(
{data.allPlanets.planets.map(p=>(
))}
);
}}
);
}
PlanetDemographics.js

import React from "react";
import gql from "graphql-tag";
import { Query } from "react-apollo";
import { DataBlock } from "./DataBlock";

const DEMOGRAPHICS_QUERY = gql`
  query {
    allPlanets(first: 4) {
      planets {
        id
        name
        population
      }
    }
  }
`;

export function PlanetDemographics() {
  return (
    <Query query={DEMOGRAPHICS_QUERY}>
      {({ loading, error, data }) => {
        if (loading) return "Loading...";
        if (error) return `Error! ${error.message}`;
        return (
          <div>
            {data.allPlanets.planets.map(p => (
              <DataBlock
                data={p}
                title={`Demographics: ${p.name}`}
                key={p.id}
              />
            ))}
          </div>
        );
      }}
    </Query>
  );
}
从“React”导入React;
从“graphql标签”导入gql;
从“react apollo”导入{Query};
从“/DataBlock”导入{DataBlock};
const DEMOGRAPHICS_QUERY=gql`
质疑{
所有行星(第一:4){
行星{
身份证件
名称
人口
}
}
}
`;
导出函数PlanetDemographics(){
返回(
{({加载,错误,数据})=>{
如果(加载)返回“加载…”;
if(error)返回`error!${error.message}`;
返回(
{data.allPlanets.planets.map(p=>(
))}
);
}}
);
}
DataBlock.js

import React from "react";

export function DataBlock({ title, data }) {
  return (
    <div
      style={{
        border: "1px solid black",
        borderRadius: "5px",
        marginBottom: "10px",
        marginRight: "10px",
        padding: "10px",
        maxWidth: "220px",
        display: "inline-block"
      }}
    >
      <h3 style={{ margin: "5px 5px", textAlign: "center" }}>{title}</h3>
      <table>
        <tbody>
          {Object.keys(data).map(key => (
            <tr key={key}>
              <td style={{ textAlign: "right" }}>{key}: </td>
              <td>{data[key]}</td>
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
}
从“React”导入React;
导出函数数据块({title,data}){
返回(
{title}
{Object.keys(data.map)(key=>(
{key}:
{data[key]}
))}
);
}

您的行星模式使用id,但缓存使用uuid。在dataIdFromObject函数中将object.uuid更改为object.id,它就可以工作了。我原以为退回到JSON.stringify会救你一命,但我猜不会。这是可行的!我很好奇为什么JSON.stringify没有拯救我,所以真正的解决方案似乎是我应该摆脱
JSON.stringify
,但通过我的实验,我无法理解为什么。
import React from "react";
import gql from "graphql-tag";
import { Query } from "react-apollo";
import { DataBlock } from "./DataBlock";

const PHYSICS_QUERY = gql`
  query {
    allPlanets(first: 4) {
      planets {
        id
        name
        diameter
        rotationPeriod
      }
    }
  }
`;

export function PlanetPhysics() {
  return (
    <Query query={PHYSICS_QUERY}>
      {({ loading, error, data }) => {
        if (loading) return "Loading...";
        if (error) return `Error! ${error.message}`;
        return (
          <div>
            {data.allPlanets.planets.map(p => (
              <DataBlock data={p} title={`Physics: ${p.name}`} key={p.id} />
            ))}
          </div>
        );
      }}
    </Query>
  );
}
import React from "react";
import gql from "graphql-tag";
import { Query } from "react-apollo";
import { DataBlock } from "./DataBlock";

const DEMOGRAPHICS_QUERY = gql`
  query {
    allPlanets(first: 4) {
      planets {
        id
        name
        population
      }
    }
  }
`;

export function PlanetDemographics() {
  return (
    <Query query={DEMOGRAPHICS_QUERY}>
      {({ loading, error, data }) => {
        if (loading) return "Loading...";
        if (error) return `Error! ${error.message}`;
        return (
          <div>
            {data.allPlanets.planets.map(p => (
              <DataBlock
                data={p}
                title={`Demographics: ${p.name}`}
                key={p.id}
              />
            ))}
          </div>
        );
      }}
    </Query>
  );
}
import React from "react";

export function DataBlock({ title, data }) {
  return (
    <div
      style={{
        border: "1px solid black",
        borderRadius: "5px",
        marginBottom: "10px",
        marginRight: "10px",
        padding: "10px",
        maxWidth: "220px",
        display: "inline-block"
      }}
    >
      <h3 style={{ margin: "5px 5px", textAlign: "center" }}>{title}</h3>
      <table>
        <tbody>
          {Object.keys(data).map(key => (
            <tr key={key}>
              <td style={{ textAlign: "right" }}>{key}: </td>
              <td>{data[key]}</td>
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
}