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

如何在Apollo Query组件查询后更新Store?写入数据为空问题

Fixing Apollo Client Local State Query Returning Empty Data

I see the issue you're running into—let's walk through how to fix this so your local @client query returns the data you expect after writing to the cache.

1. First: Define the processChangeRequests Field in Your Local Schema

Apollo Client needs to know the structure of your local state fields to properly cache and retrieve them. If you haven't already, add this definition to your local schema:

// Define the type for your process change request
type ProcessChangeRequest {
  summary: String
  type: String
  created_by: String
  created_date: String
  modified_by: String
  modified_date: String
  status: String
  projekt: String
  assigned_user_overall_responsibility: String
  assigned_user_status_im_workflow: String
  planned_target_date: String
  description: String
  implicated: String
  live_item_id: String
  related_process: String
  to_do: String
  priority: String
  scope: String
}

// Add the field to your root Query type
type Query {
  processChangeRequests: [ProcessChangeRequest] @client
}

Without this, Apollo doesn't recognize the shape of your local data, so it can't properly return it when you query with @client.

2. Use cache.writeQuery Instead of client.writeData

writeData works for simple local state, but when matching the structure of a specific query (like the one in Lanes.js), cache.writeQuery is more reliable—it ensures the data you write exactly matches the query structure Apollo will use to fetch it later.

Update your Dashboard.js code like this:

<Query query={GET_ITEMS({ uid: user.uid })}>
  {({ loading, data: { GetProcessChangeRequests }, client }) => {
    if (loading) return (
      <Segment>
        <Icon loading name='spinner' /> Loading items ....
      </Segment>
    );

    // Match the exact query structure from Lanes.js
    client.cache.writeQuery({
      query: gql`
        {
          processChangeRequests @client {
            summary, type, created_by, created_date, modified_by, modified_date, status, projekt, assigned_user_overall_responsibility, assigned_user_status_im_workflow, planned_target_date, description, implicated, live_item_id, related_process, to_do, priority, scope
          }
        }
      `,
      data: {
        processChangeRequests: [...GetProcessChangeRequests] // Spread syntax is cleaner than Object.assign here
      }
    });

    return (
      <Container>
        <div>{ ITEM_TITLE_DICTIONARY[visibilityFilter] }</div>
        <Divider />
        <Lanes user={user} visibilityFilter={visibilityFilter} {...this.props} />
      </Container>
    );
  }}
</Query>

3. Verify Your Server Data Has All Required Fields

Double-check that GetProcessChangeRequests (the data from your server query) includes every field you're trying to query in Lanes.js. If any field is missing from the server response, Apollo won't populate it in the local cache, leading to empty or incomplete results.

Add a quick log to confirm:

console.log('Server response data:', GetProcessChangeRequests);

If fields are missing, either update your server query to return them, or adjust your local schema to mark optional fields as nullable (e.g., summary: String is already nullable, only add ! if you're sure the field will always exist).

4. Avoid Repeated Cache Writes in Render

Right now, your code writes to the cache every time the component renders, which can cause unnecessary re-renders and cache inconsistencies. If Dashboard is a class component, move the fetch-and-cache logic to lifecycle methods:

class Dashboard extends React.Component {
  state = { loading: true };

  componentDidMount() {
    this.updateLocalCache();
  }

  componentDidUpdate(prevProps) {
    // Re-run only when user or filter changes
    if (prevProps.user?.uid !== this.props.user?.uid || prevProps.visibilityFilter !== this.props.visibilityFilter) {
      this.setState({ loading: true });
      this.updateLocalCache();
    }
  }

  updateLocalCache = async () => {
    const { user, client } = this.props;
    try {
      const { data } = await client.query({ query: GET_ITEMS({ uid: user.uid }) });
      client.cache.writeQuery({
        query: gql`
          {
            processChangeRequests @client {
              summary, type, created_by, created_date, modified_by, modified_date, status, projekt, assigned_user_overall_responsibility, assigned_user_status_im_workflow, planned_target_date, description, implicated, live_item_id, related_process, to_do, priority, scope
            }
          }
        `,
        data: { processChangeRequests: [...data.GetProcessChangeRequests] }
      });
      this.setState({ loading: false });
    } catch (err) {
      console.error('Failed to update cache:', err);
      this.setState({ loading: false });
    }
  };

  render() {
    const { loading } = this.state;
    if (loading) return (
      <Segment>
        <Icon loading name='spinner' /> Loading items ....
      </Segment>
    );
    return (
      <Container>
        <div>{ ITEM_TITLE_DICTIONARY[this.props.visibilityFilter] }</div>
        <Divider />
        <Lanes user={this.props.user} visibilityFilter={this.props.visibilityFilter} {...this.props} />
      </Container>
    );
  }
}

5. (Simpler Alternative) Pass Data Directly as Props

If you don't need to share processChangeRequests with other components via the Apollo cache, skip the local state entirely and pass the data directly to Lanes:

// Dashboard.js
<Query query={GET_ITEMS({ uid: user.uid })}>
  {({ loading, data: { GetProcessChangeRequests } }) => {
    if (loading) return (
      <Segment>
        <Icon loading name='spinner' /> Loading items ....
      </Segment>
    );
    return (
      <Container>
        <div>{ ITEM_TITLE_DICTIONARY[visibilityFilter] }</div>
        <Divider />
        <Lanes 
          user={user} 
          visibilityFilter={visibilityFilter} 
          processChangeRequests={GetProcessChangeRequests}
          {...this.props} 
        />
      </Container>
    );
  }}
</Query>

// Lanes.js
// No need for a Query component—just use the prop
const Lanes = ({ processChangeRequests }) => {
  return <div>{ JSON.stringify(processChangeRequests) }</div>;
};

This is the most straightforward fix if you don't need the data in the global Apollo cache.


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:58:30