Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to force a fetch in Relay modern

Tags:

relayjs

My top-level component includes a settings dialog that includes the user's credentials. When a change is made in that dialog and the dialog is dismissed (state is changed to dialogOpen=false), I want to force a new fetch from the server since the credentials may have changed. In Relay classic, the top-level component includes a Relay.RootContainer and so I just passed forceFetch=true to that RootContainer. In Relay modern, my top-level component includes a QueryRenderer. So how do I force the refetch in this case?

I found this issue, https://github.com/facebook/relay/issues/1684, which seems to indicate that the QueryRenderer always refetches, but this doesn't seem to be the case in my testing. At least, I'm not seeing my fetchQuery get called after the state change/refresh when the settings dialog is closed. I think I'm probably not completely understanding the statements in that issue.

Can anyone clarify?

like image 942
bjlevine Avatar asked Jun 23 '17 14:06

bjlevine


2 Answers

OK, I think I figured out my disconnect here. In checking the source for QueryRenderer (don't know why I didn't do this in the first place), I saw that a fetch will occur if props.variables changes. So I just defined a boolean instance variable called refetch and flip its value when my dialog is dismissed:

<QueryRenderer
  environment={environment}
  query={query}
  variables={{refetch: this.refetch}}

Since this doesn't seem to well documented, I'll mention here that QueryRenderer will re-fetch when any of the following conditions is true:

  • current query parameter is not equal to the previous query parameter.
  • current environment parameter is not equal to the previous environment parameter.
  • current variables parameter is not equal to the previous variables parameter.
like image 66
bjlevine Avatar answered Nov 09 '22 05:11

bjlevine


You can use the retry function that's passed to QueryRenderer's render.

<QueryRenderer
  environment={environment}
  query={graphql`
    query MyQuery($exampleUserId: String!) {
      user(userId: $exampleUserId) {
        favoriteIceCream
      }
    }
  `}
  render={({ error, props, retry }) => {
    // Here, you could call `retry()` to refetch data
    // or pass it as a prop to a child component.
    return (
      <IceCreamSelectionView refetchData={retry} user={props.user} />
    )
  }} />
like image 12
Kevin Avatar answered Nov 09 '22 07:11

Kevin