简体   繁体   中英

React-apollo Typescript errors when using graphql to pass props to higher order component

I'm running into some issues trying to connect a React class component to my Apollo cache data, which for now is just local.

I'm following the docs from here , but I'm running into trouble where VSCode and Webpack are throwing errors when I access data like this: this.props.data.playing , which is how I'd expect to access it. Despite this, in the browser this returns the correct data. However if I access data like this: this.props.data.data.playing the typecheck passes but throws an error in the browser console ( Cannot read property 'playing' of undefined ). So I'm reasonably sure this is a type definition error, but I'm not sure where I'm going wrong.

I should point out that NPM and all packages are updated.

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 };

This is not typing error - typical error for trying access to not ready data - usually in render() , when data not arrived yet.

Place console log after if (this.props.data.data) { ... and bad logging argument, should be console.log(this.props.data.data.playing); - response named data (a bit missleading).

The solution here was to not wrap the AudioData type into Response , despite the fact that they use that pattern in the documentation. I updated the following lines:

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM