Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Container is not rerendered when calling refetch #2553

Closed
ntelkedzhiev opened this issue Oct 24, 2018 · 15 comments
Closed

Container is not rerendered when calling refetch #2553

ntelkedzhiev opened this issue Oct 24, 2018 · 15 comments

Comments

@ntelkedzhiev
Copy link

ntelkedzhiev commented Oct 24, 2018

I'm using RelayCache to load the initial data and then calling refetch in componentDidMount():

 this.props.relay.refetch(refetchVariables, null, () => console.log('Refetch Done!'), {force: true})

However, the QueryRenderer does not render when the refetch is executed, nor the callback of the refetch function is called. What is more interesting is that if I wrap the refetch call into a setTimeout everything works fine:

  setTimeout(() => {
      this.props.relay.refetch(refetchVariables, null, error => console.log('Refetch done'), {force: true});
  });

Any suggestions why this is happening?

@sibelius
Copy link
Contributor

QueryRenderer should be used only for the first query (on root component, like the first react component in a route)

Only your refetchContainer should rerender, check the docs https://facebook.github.io/relay/docs/en/refetch-container.html

QueryRenderer won't rerender if you won't change variables

@ntelkedzhiev
Copy link
Author

@sibelius Issue persists even if the variables are different. The RefetchContainer does not rerender.

@sibelius
Copy link
Contributor

create a small repro so we can test it

@ntelkedzhiev
Copy link
Author

@jgcmarins
Copy link
Contributor

@ntelkedzhiev I've made a comment here: ntelkedzhiev/relay-refetch@2b1084f#r31043442

@ntelkedzhiev
Copy link
Author

@jgcmarins Thanks but this is unrelated (and false according to the docs).

@ntelkedzhiev
Copy link
Author

Any ideas?

@josephsavona
Copy link
Contributor

The most likely explanation for a RefetchContainer not updating is that the data being refetched doesn't overlap with the data that the fragment is selecting - usually because the variables don't line up. I would double check the query and variables.

@jgcmarins
Copy link
Contributor

relay-dev-tools can help you with RelayNetworkLogger
You can also check network tab

@ntelkedzhiev
Copy link
Author

I did check the query and the variables. None of the usual solutions for this type of problems make sense here.

As I said above, wrapping the relay refetch call in a simple setTimeout() solves the issue which is what makes this issue "interesting". Please see the demo I referenced.

@ntelkedzhiev
Copy link
Author

ntelkedzhiev commented Oct 31, 2018

The problem is here:

// If the environment has changed or props point to new records then
// previously fetched data and any pending fetches no longer apply:
// - Existing references are on the old environment.
// - Existing references are based on old variables.
// - Pending fetches are for the previous records.
if (this.state.resolver !== prevState.resolver) {
prevState.resolver.dispose();
this._queryFetcher && this._queryFetcher.dispose();
this._refetchSubscription && this._refetchSubscription.unsubscribe();
this._subscribeToNewResolver();
}

For some reason the first refetch request passes the if. Maybe because it was initiated before the payload from the initial request (from the QueryRenderer) was received. After that happened, the initial payload rendered the props so they point to new records (compared to where they pointed to at the time of the first refetch).

The relay code makes sense so I guess I'll have to wait until the first payload is rendered and only then refetch. What do you guys think?

@xyy94813
Copy link

pass render-variables can resolve this issue in my project.

const q = { effecting_true: 1 };
const vars = {
  id: data?.id,
  disablementQ: q,
};
refetchData(vars, {
  q,
});
 export default createRefetchContainer(
  DriverDisablementCard,
  {
    data: graphql`
      fragment DriverDisablementCard_data on Driver
        @argumentDefinitions(q: { type: "JsonObject" }) {
        id
        disablements(before: null, first: 30, q: $q) {
          nodes {
            ...DriverDisablementTable_data
          }
        }
      }
    `,
  },
  graphql`
    query DriverDisablementCardQuery($id: ID!, $disablementQ: JsonObject) {
      data: node(id: $id) {
        ...DriverDisablementCard_data @arguments(q: $disablementQ)
      }
    }
  `
);

@stale
Copy link

stale bot commented Dec 25, 2020

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the wontfix label Dec 25, 2020
@stan-sack
Copy link

@ntelkedzhiev did you ever work a way to do this other than waiting for the first payload to render? its still an issue in latest relay.

@stale stale bot removed the wontfix label Mar 2, 2022
@sibelius
Copy link
Contributor

Migrate to relay hooks, if the issue still valid, open another issue

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants