tharris
tharris

Reputation: 2242

Apollo (react-apollo): Force a re-query even if query didn't change

I have a GraphQL end-point that returns a random name each time it is queried.

It seems that Apollo's Query object won't re-query if the query itself doesn't change. Here is a snippet of the code:

class RandomName extends React.Component {
render() {
  const query = gql`
			query name($gender: String, $top: Int) {
				name(gender: $gender, top: $top) {
					firstName
					gender
					surname
				}
			}
		`;
		return (
			<Query
				query={query}
				variables={{ gender: this.props.gender, top: this.props.top }}
				fetchPolicy="network-only"
			>
				{({ loading, error, data }) => {
        	if (loading) return <p>Loading...</p>;
					if (error) return <p>Error</p>;
          return <p>{name.firstName} {name.surname}</p>
        }}
      </Query>
  }
}

If the gender or top variables change, the query will get re-run, but if I have a button that forces a re-query, it won't re-run the query if the query is exactly the same as the last time it ran. I read the docs and this seems to be proper behavior.

Here is code that is inside the parent component:

onClick() {
		this.setState({
			sendGender: this.state.currentGender,
			sendTop: this.state.currentTop,
		});
		this.forceUpdate();
}

render() {
<Button onClick={() => this.onClick()}>Get Name</Button>
}

Any ideas?

Thank you!

Upvotes: 2

Views: 2232

Answers (1)

tharris
tharris

Reputation: 2242

I found a workaround. If I move the button to be in the Query component, I can use the refetch() function. I still need to be able to change the query if my parent object has changed, though, so I can pass a function from my parent object to return its state:

< Query
query = {
  query
}
variables = {
  {
    gender: this.props.gender,
    top: this.props.top
  }
}
fetchPolicy = "network-only" >
  {
    ({
      loading,
      error,
      data,
      refetch
    }) => {
      // Not shown: dealing with query
      // New button here...
      <button
        onClick = {() => {
            refetch(this.props.refresh());
          }
        }>
        Reload
      </button>

Then in the parent component, here is the refresh() function that gets passed:

onRefresh() {
  return { gender: this.state.currentGender, top: this.state.currentTop };
}

Upvotes: 1

Related Questions