首页 > 解决方案 > 为什么 apollo 客户端网络请求取消了两次?

问题描述

我的 apollo/client - useQuery 加载两次,这基于正常流程是正常的,但是当我打开 devtools 上的网络选项卡并注意到奇怪的东西时。

我有 2 个取消的请求,我不知道为什么。

在此处输入图像描述

在此处输入图像描述

在此处输入图像描述

我的代码与 apollo 客户端文档相同

function Dogs({ onDogSelected }) {
  const { loading, error, data } = useQuery(GET_DOGS);

  if (loading) return 'Loading...';
  if (error) return `Error! ${error.message}`;

  return (
    <select name="dog" onChange={onDogSelected}>
      {data.dogs.map(dog => (
        <option key={dog.id} value={dog.breed}>
          {dog.breed}
        </option>
      ))}
    </select>
  );
}

有人遇到过这个吗?

标签: graphqlnext.jsapollo-client

解决方案


很可能您的代码在_app.js您实例化的地方或任何地方apolloClient运行多次(在重新渲染时),丢弃旧客户端并创建一个新客户端,并且当前的 apollo 调用(附加到旧实例)被取消然后重新运行一次新创建apolloClient的被传递给ApolloProvider.

对此的解决方案是使apolloClient不可变并返回相同的实例,除非需要重新实例化。

就我而言,我们是这样设置的:

_app.tsx:
const App = (props) => {
  const apolloClient = useApollo({ language, location });

  return (
     <ApolloProvider client={apolloClient}>
       {...}
     </ApolloProvider>
  );
}

apollo-client.ts

WRONG WAY:
export default function useApollo(config) {
  return useMemo(() => createApolloClient(config), [config]);
}

GOOD WAY:
export default function useApollo() {
  return useMemo(() => createApolloClient(config), [config.language, config.location]);
}

请注意 useMemo 没有完成这项工作,因为它正在比较总是不同的对象(引用)。

这只是需要注意的一件事,但还有许多其他原因apolloClient可以让您重新实例化。


推荐阅读