How to force Apollo Query component to re-run query when parent component re-renders How to force Apollo Query component to re-run query when parent component re-renders reactjs reactjs

How to force Apollo Query component to re-run query when parent component re-renders


I had almost a similar situation which I solved with fetchPolicy attribute:

<Query fetchPolicy="no-cache" ...

The task was to load some details from server by clicking on a list item.

And if I wanted to add an action to force re-fetching the query (such as modifying the details), I first assigned the refetch to this.refetch:

<Query fetchPolicy="no-cache" query={GET_ACCOUNT_DETAILS} variables=... }}>  {({ data: { account }, loading, refetch }) => {  this.refetch = refetch;...

And in the specific action that I wanted the refetch to happen, I called:

this.refetch();


It seems to me that the Query component doesn't necessarily need to be inside this ParentComponent.

In that case, I would move the Query component up, since I would still be able to render other stuff while I don't have results in the ChildComponent. And then I would have access to the query.refetch method.

Note that in the example I added the graphql hoc, but you can still use Query component around <ParentComponent />.

class ParentComponent extends React.Component {    componentDidUpdate(prevProps) {        if (this.props.refetchId !== prevProps.refetchId) {            const otherData = this.processData() // do something            //   won't need this anymore, since refetch will cause the Parent component to rerender)            //   this.setState({otherData}) // this forces component to reload             this.props.myQuery.refetch(); // >>> Refetch here!        }    }    render() {        const {            otherData        } = this.state;        return <ChildComponent gqlData={this.props.myQuery} stateData={otherData} />;    }}export graphql(MY_QUERY, {    name: 'myQuery'})(ParentComponent);


Could you refetch in parent component? Once the parent component get an update, then you can evaluate whether to trigger a fetch or not.

I have done it without using Query like the following:

class ParentComp extends React.Component {    lifeCycleHook(e) { //here        // call your query here        this.props.someQuery()    }    render() {        return (            <div>                <Child Comp data={this.props.data.key}> //child would only need to render data            </div>        );    }}export default graphql(someQuery)(SongCreate);

So you can trigger your fetch anytime you want it to. You can get the query as a prop in this case.

For your case, you would put your query into a prop using export default graphql(addSongQuery)(SongCreate);. Then call it in your lifecyclehooks DidUpdate.

Another options is to use refetch on Query.

<Query    query={GET_DOG_PHOTO}    variables={{ breed }}    skip={!breed}  >    {({ loading, error, data, refetch }) => {      if (loading) return null;      if (error) return `Error!: ${error}`;      return (        <div>          <img            src={data.dog.displayImage}            style={{ height: 100, width: 100 }}          />          <button onClick={() => refetch()}>Refetch!</button>        </div>      );    }}  </Query>

The second method would require you pass something down to your child, which isn't really all that bad.