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

React中Apollo Boost两类问题:变量变更不自动重取与外部触发重取

Hey there! Let's break down your two Apollo Boost questions one by one, using your GalleryPage scenario as context:

a) 为什么Apollo不会在变量变更时自动重新获取数据?

Apollo's Query component relies on shallow comparison of the variables prop to decide whether to re-run the query. The most common reason it doesn't trigger automatically is that your filter object's reference hasn't changed—even if you modified its internal values.

For example, if you update your state like this (which mutates the original object):

// ❌ Bad: Modifies the existing filters object directly
this.state.filters.brands.push(2);
this.setState({ filters: this.state.filters });

Apollo won't detect a change because the filters object still points to the same reference in memory.

Fix: Always return a new object reference

When updating your filters state, create a new object/array instead of mutating the old one. This lets Apollo's shallow comparison pick up the change:

// ✅ Good: Creates a new filters object with updated values
this.setState(prevState => ({
  filters: {
    ...prevState.filters,
    brands: [...prevState.filters.brands, 2] // New array for brands
  }
}));

Then pass this updated state directly to your Query component's variables prop:

<Query
  query={YOUR_GALLERY_QUERY}
  variables={{ filters: this.state.filters }}
>
  {/* Render prop content */}
</Query>

Also double-check that your GraphQL query actually uses the $filters variable—if the query doesn't depend on those variables, changing them won't trigger a re-fetch.

b) 如何在Query组件外部调用refetch方法?

There are two straightforward ways to do this in a class component:

Method 1: Save the refetch method to your component instance

You can capture the refetch function provided by the Query component's render prop and store it on your class instance. Then you can call it from anywhere in your parent component:

class GalleryPage extends Component {
  constructor () {
    super();
    this.state = {
      filters: { brands: [1, 3], filetypes: [4, 5, 6] },
    };
    this.galleryRefetch = null; // Hold refetch reference here
  }

  handleFilterUpdate = () => {
    // Call refetch whenever you need to (e.g., after updating filters)
    if (this.galleryRefetch) {
      this.galleryRefetch({ filters: this.state.filters });
    }
  };

  render() {
    return (
      <div>
        {/* Example: Button to trigger refetch */}
        <button onClick={this.handleFilterUpdate}>Apply Filters & Refresh</button>

        <Query
          query={YOUR_GALLERY_QUERY}
          variables={{ filters: this.state.filters }}
        >
          {({ loading, error, data, refetch }) => {
            // Save refetch to component instance
            this.galleryRefetch = refetch;

            if (loading) return <p>Loading...</p>;
            if (error) return <p>Oops, something went wrong!</p>;

            return <GalleryComponent data={data} />;
          }}
        </Query>
      </div>
    );
  }
}

Method 2: Use Apollo Client's direct query method

If you wrap your component with the withApollo higher-order component, you can access the Apollo Client instance directly and run queries manually:

import { withApollo } from 'react-apollo';

class GalleryPage extends Component {
  // ... constructor and state

  handleFilterUpdate = async () => {
    try {
      const result = await this.props.client.query({
        query: YOUR_GALLERY_QUERY,
        variables: { filters: this.state.filters },
        // Optional: Set fetchPolicy if you need fresh data
        fetchPolicy: 'network-only'
      });
      // Handle the returned data here if needed
    } catch (error) {
      // Handle errors
      console.error('Query failed:', error);
    }
  };

  // ... render method
}

// Wrap component to inject Apollo Client
export default withApollo(GalleryPage);

Note: This method doesn't automatically update the Query component's cached data unless you specify the right fetch policy, so use it only if you need full manual control.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 12:24:33