首页 > 解决方案 > 有承诺的用户 Apollo GraphQL

问题描述

我正在使用 GraphQL 构建 React 本机应用程序。当应用程序进入前台时,我必须在收到来自本机层的事件后进行数据调用。

const eventEmitter = new NativeEventEmitter(NativeModules.EventEmitter)
    if (eventEmitter.listeners(Constants.callBacks.NativeSideEventReceived).length === 0) {
      eventEmitter.addListener(Constants.callBacks.NativeSideEventReceived, (linearIngressData) => {
        
const {data, error} = useQuery(CONTENT, {
  variables: {
    deviceLocale,
    contentId,
    contentType: Json
  },
  skip: shouldSkip
})


      })
    }

问题是,我不能在事件处理程序中使用 useQuery,因为我必须在反应组件中使用 useQuery。

一旦数据可用,我就必须调度一些事件。

const dispatch = useContext(DispatchContext)
if (data) {
    dispatch({
      type: '_CHANGE',
      content: data.content
    })
  }

我如何使用带有 GQL 的 promise 对象来确保数据可用。如果我在数据可用之前收到NativeSideEventReceived,那么我必须等到我有可用的响应来调度状态事件。

我不能使用 useQuery 的 onComplete 函数,因为要使用 useQuery,我已将其移至功能组件,但是一旦我收到事件,则只需调度该事件。使用 onComplete 将无法保证在接收到事件NativeSideEventReceived后将调用 onComplete 。

谢谢

标签: javascriptandroidreact-nativegraphqlgraphql-js

解决方案


作为 Vue 用户,我创建了这个可组合的小函数,以便拥有 apollo API 的承诺版本。

import { ApolloQueryResult, OperationVariables } from '@apollo/client';
import { useQuery } from '@vue/apollo-composable';
import { DocumentParameter, VariablesParameter } from '@vue/apollo-composable/dist/useQuery';
import { ref } from 'vue';


// promisification of the apollo query
export function useApolloQuery<TResult = any, TVariables extends OperationVariables = OperationVariables>(document: DocumentParameter<TResult, TVariables>, variables: () => VariablesParameter<TVariables>) {
  const enableLoginQuery = ref(false);
  const { onResult, loading: queryLoading, onError } = useQuery(
    document, 
    variables,
    () => ({
      enabled: enableLoginQuery.value,
      notifyOnNetworkStatusChange: false
    }));

  const apolloQuery = () => new Promise<ApolloQueryResult<TResult>>((resolve, reject) => {
    console.log('calling query apollo');
    enableLoginQuery.value = true;
    onResult(res => {
      if (!res.loading) {
        enableLoginQuery.value = false;
        
        if (!res.data) {
          reject('no data');
        }
        resolve(res);
      }
    });
    onError(err => {
      enableLoginQuery.value = false;
      console.error(err)
      reject(err);
    });
  });

  return {
    apolloQuery,
    queryLoading
  };
}

在示例查询中,您可以像这样使用它:

import {useApolloQuery} from '... wherever that is';

const { apolloQuery } = useApolloQuery(UserQueryDoc, () => ({
  username: form.value.username,
  otherVars: 'other sample var'
}));
const res = await apolloQuery();

全部完全打字。我使用 graphql-tools 来生成类型。


推荐阅读