You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Apollo Link State配置异常:查询返回空对象求助

Let's work through your issues with Apollo Link State—first the 400 error, then the empty query response, and finally why removing defaults breaks query recognition. I've dealt with these exact pitfalls before, so let's dive in.

First: Why You Got the 400 Status Code

That initial 400 error almost always means your local query was being sent to your remote GraphQL server instead of being handled by Apollo Link State. Here's why that happens:

  • Link order is wrong: The stateLink (from withClientState) needs to come before your httpLink in the Apollo Link chain. If you put httpLink first, Apollo sends every query to the remote server, which has no clue what your @client-annotated networkStatus field is.
  • Missing typeDefs: If you didn't define the networkStatus field in your local schema, Link State doesn't recognize the query as local, so it passes it along to the remote server.

Next: Why the Query Returns an Empty Object

After fixing the 400, getting an empty object usually boils down to a missing __typename or misaligned cache structure. Apollo Cache relies heavily on __typename to map data to your schema. Here are the common fixes:

1. Ensure defaults Includes __typename

Your default state needs to explicitly include the type name for the networkStatus object. Without it, Apollo can't find the data in the cache. For example:

const defaults = {
  networkStatus: {
    __typename: 'NetworkStatus', // This is critical!
    isConnected: true
  }
};

2. Verify Your Local Schema (typeDefs)

Double-check that your typeDefs correctly defines the NetworkStatus type and the networkStatus query field:

const typeDefs = `
  type NetworkStatus {
    isConnected: Boolean!
  }

  type Query {
    networkStatus: NetworkStatus!
  }
`;

If the field names or types don't match your query (e.g., spelling isConnected wrong), Apollo won't return data.

3. Check Resolver Logic (If You're Using One)

If you added a resolver for networkStatus, make sure it's correctly reading from the cache. A common mistake is not falling back to the default state if the cache is empty:

const resolvers = {
  Query: {
    networkStatus: (_, __, { cache }) => {
      // Try reading from cache first
      const cachedData = cache.readQuery({ 
        query: gql`{ networkStatus @client { isConnected } }` 
      });
      // Fall back to defaults if nothing is cached
      return cachedData?.networkStatus || defaults.networkStatus;
    }
  }
};

If you don't have a resolver, Apollo will automatically read from the cache—so getting the defaults structure right is even more important.

Why Removing defaults Breaks Query Recognition

When you remove defaults, Apollo Link State still recognizes the query (thanks to typeDefs), but there's no initial data in the cache, and if you don't have a resolver that returns a value, it will return null or an empty object. Wait, but you said the query "can't be recognized"—that probably means your typeDefs wasn't properly linked to the client. Make sure you're passing typeDefs to withClientState and that the client is using the combined link chain.

Full Working Setup Example

Let's put it all together with a correct configuration to avoid these issues:

import { ApolloClient, InMemoryCache, HttpLink, ApolloLink, gql } from '@apollo/client';
import { withClientState } from 'apollo-link-state';

// 1. Define your local schema
const typeDefs = `
  type NetworkStatus {
    isConnected: Boolean!
  }

  type Query {
    networkStatus: NetworkStatus!
  }

  # Optional: Mutation to update network status later
  type Mutation {
    updateNetworkStatus(isConnected: Boolean!): Boolean
  }
`;

// 2. Set initial state with __typename
const defaults = {
  networkStatus: {
    __typename: 'NetworkStatus',
    isConnected: navigator.onLine // Use browser's online status as initial value
  }
};

// 3. Add resolvers (optional but useful for updates)
const resolvers = {
  Mutation: {
    updateNetworkStatus: (_, { isConnected }, { cache }) => {
      cache.writeData({
        data: {
          networkStatus: {
            __typename: 'NetworkStatus',
            isConnected
          }
        }
      });
      return isConnected;
    }
  }
};

// 4. Configure links in the correct order
const httpLink = new HttpLink({ uri: '/your-graphql-endpoint' });
const cache = new InMemoryCache();

const stateLink = withClientState({
  cache,
  defaults,
  typeDefs,
  resolvers
});

// State link first, then HTTP link
const client = new ApolloClient({
  link: ApolloLink.from([stateLink, httpLink]),
  cache
});

// 5. Define your query
const GET_NETWORK_STATUS = gql`
  query GetNetworkStatus {
    networkStatus @client {
      isConnected
    }
  }
`;

// Test the query
client.query({ query: GET_NETWORK_STATUS })
  .then(result => console.log('Network status:', result.data.networkStatus))
  .catch(err => console.error('Query error:', err));

Quick Troubleshooting Checklist

  • Confirm stateLink is before httpLink in the link chain.
  • Check that defaults includes __typename for all objects.
  • Verify typeDefs matches your query's fields and types.
  • Test manually writing to the cache with client.writeData() to see if the query picks up the change.
  • Ensure your Apollo Client and apollo-link-state versions are compatible (older versions might have different API behavior).

内容的提问来源于stack exchange,提问作者Evanss

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 06:41:30