使用 graphql 将道具传递给高阶组件时出现 React-apollo Typescript 错误

Posted

技术标签:

【中文标题】使用 graphql 将道具传递给高阶组件时出现 React-apollo Typescript 错误【英文标题】:React-apollo Typescript errors when using graphql to pass props to higher order component 【发布时间】:2020-09-10 15:24:23 【问题描述】:

我在尝试将 React 类组件连接到我的 Apollo 缓存数据时遇到了一些问题,目前这只是本地的。

我正在关注来自here 的文档,但是当我访问这样的数据时,VSCode 和 Webpack 抛出错误时遇到了麻烦:this.props.data.playing,这就是我希望访问它的方式。尽管如此,在浏览器中这会返回正确的数据。但是,如果我访问这样的数据:this.props.data.data.playing 类型检查通过但在浏览器控制台中引发错误 (Cannot read property 'playing' of undefined)。所以我有理由确定这是一个类型定义错误,但我不确定我哪里出错了。

我应该指出,NPM 和所有软件包都已更新。

type AudioData = 
  bpm: number;
  beatsPerBar: number;
  playing: boolean;
  metronomeSound: string;
  playPosition: number;
  playStartTime: number;
;

type Response = 
  data: AudioData;
;

class ConnectedWorkspaceAudio extends React.Component<
  ChildProps<, Response>
> 
  _context: AudioContext;
  _scheduler: Scheduler;
  _recorder: Recorder;

  constructor(props: ChildProps<, Response>) 
    super(props);
  

  componentDidMount(): void 
    /***/
  

  componentDidUpdate(prevProps: ChildProps<, Response>): void 
    console.log(this.props.data.playing); // Fails type check, prints correctly in browser.
    if (this.props.data.data) 
      if (this.props.data.data.playing && !prevProps.data.data.playing)  // Passes type check, gives console error in browser.
        useApolloClient().writeData( data:  playing: true  );
      
      if (!this.props.data.data.playing && prevProps.data.data.playing) 
        useApolloClient().writeData( data:  playing: false  );
      
    
  

  /** There's some more methods including render() I don't believe are relevant. */



const WORKSPACE_AUDIO_QUERY = gql`
  query Audiostate 
    bpm @client
    beatsPerBar @client
    playing @client
    metronomeSound @client
    playPosition @client
    playStartTime @client
  
`;

const WorkspaceAudio = graphql<, Response>(WORKSPACE_AUDIO_QUERY)(
  ConnectedWorkspaceAudio
);

export  WorkspaceAudio ;

【问题讨论】:

【参考方案1】:

这不是输入错误 - 尝试访问未准备好的数据的典型错误 - 通常在 render(),当数据尚未到达时。

console log 放在if (this.props.data.data) 之后......并且错误的日志记录参数应该是console.log(this.props.data.data.playing); - 名为data 的响应(有点误导)。

【讨论】:

在原始问题中看到:“尽管如此,在浏览器中这会返回正确的数据。”他们的问题不是数据没有准备好。我发布了我的解决方案。 解决相同问题的其他方法 - 不正确的对象 [深度] 访问 - 我修复了您的数据声明的代码,您更改了数据结构 - 仍然没有输入错误 ;)【参考方案2】:

这里的解决方案是不要将 AudioData 类型包装到 Response 中,尽管事实上他们在文档中使用了该模式。我更新了以下几行:

class ConnectedWorkspaceAudio extends React.Component<
  ChildProps<, AudioData>

...

const WorkspaceAudio = graphql<, AudioData>(WORKSPACE_AUDIO_QUERY)(
  ConnectedWorkspaceAudio
);

【讨论】:

以上是关于使用 graphql 将道具传递给高阶组件时出现 React-apollo Typescript 错误的主要内容,如果未能解决你的问题,请参考以下文章

高阶组件中功能组件的道具

在设置子组件的数组状态并将其通过反应测验传递回父组件时出现问题

通过 React 高阶组件传递子道具的正确 TypeScript 类型

将状态作为道具传递给子组件不起作用

Redux Form - 渲染以下自定义组件时出现错误?不知道为啥?

作为道具传递时,graphql refetch 的类型是啥?