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

Component is Re-rendering even if data is equal #1864

Closed
stephanoparaskeva opened this issue Feb 26, 2021 · 6 comments
Closed

Component is Re-rendering even if data is equal #1864

stephanoparaskeva opened this issue Feb 26, 2021 · 6 comments

Comments

@stephanoparaskeva
Copy link

stephanoparaskeva commented Feb 26, 2021

Problem

This polling causes re-render every time. Even if data is equal:

  const { data: matches } = useQuery<Array<ITournamentMatch>>(
    ["matches", endpoint],
    getMatchData,
    {
      initialData: [],
      refetchInterval: 10000,
    }
  );

Even after adding this check, it still causes re-render:

  const { data: matches } = useQuery<Array<ITournamentMatch>>(
    ["matches", endpoint],
    getMatchData,
    {
      initialData: [],
      refetchInterval: 10000,
      isDataEqual: (oldData, newData) => {
        console.log(JSON.stringify(oldData) === JSON.stringify(newData));
        return JSON.stringify(oldData) === JSON.stringify(newData);
      },
    }
  );

  console.log("runs", Math.random());

Console every 10 seconds outputs:

MatchList.tsx:62 runs 0.32818948818415516
MatchList.tsx:58 true
MatchList.tsx:62 runs 0.7568808987116595


On a different component the same occurs:

  const { data: match } = useQuery<ITournamentMatch>("match", getMatch, {
    initialData: {
      externalId: null,
      id: null,
      matchStatus: "",
      matchTime: "",
      matchTimeUTC: "",
      matchType: "",
      teamA: {} as ITournamentMatchTeam,
      teamB: {} as ITournamentMatchTeam,
    },
    refetchInterval: 10000,
    isDataEqual: (oldData, newData) =>
      JSON.stringify(oldData) === JSON.stringify(newData),
  });

  console.log('runs', Math.random())

LiveMatch.tsx:46 runs 0.20183955814094712
LiveMatch.tsx:46 runs 0.9209062385862188

@TkDodo
Copy link
Collaborator

TkDodo commented Feb 26, 2021

That is happening because your component transitions to isFetching: true when there is a background update, and then back to isFetching: false. Try notifyOnChangeProps: 'tracked' or giving an Array of props you want to "track".

usually, the re-renders don't matter. your component should be able to render every 10 seconds without showing impact. Imagine there are changes in the data one every poll - then you are also rendering, and need to be able to handle that :)

@stephanoparaskeva
Copy link
Author

stephanoparaskeva commented Feb 26, 2021

That is happening because your component transitions to isFetching: true when there is a background update, and then back to isFetching: false. Try notifyOnChangeProps: 'tracked' or giving an Array of props you want to "track".

usually, the re-renders don't matter. your component should be able to render every 10 seconds without showing impact. Imagine there are changes in the data one every poll - then you are also rendering, and need to be able to handle that :)

This worked but is a little bit confusing:

      notifyOnChangeProps: ["isLoading", "isSuccess", "data", "isError", "status"],

It starts as "status" = "success"
nothing really changes from the first load

Any way I can listen to the loading status again. I want to know if data loads when dependancy array changes but that is all I care about

@TkDodo
Copy link
Collaborator

TkDodo commented Feb 26, 2021

well it depends on which fields your component is using. Are you also displaying an error ? If so, you also want to re-render when there is an error, otherwise, it will not be shown ... That is why we introduced notifyOnChangeProps: 'tracked', where react-query will track which properties of the returned queryInfo are actually used during rendering, and only re-render if one of those fields change.

@stephanoparaskeva
Copy link
Author

stephanoparaskeva commented Mar 1, 2021

I updated to to latest and notifyOnChangeProps: 'tracked' gives me the error

Uncaught TypeError: notifyOnChangeProps.some is not a function
    at _loop (webpack:///./node_modules/react-query/es/core/queryObserver.js?:359)

@TkDodo
Copy link
Collaborator

TkDodo commented Mar 1, 2021

which version are you running? This feature was added in 3.6.0 (minor release): https://github.com/tannerlinsley/react-query/releases/tag/v3.6.0

@stephanoparaskeva
Copy link
Author

which version are you running? This feature was added in 3.6.0 (minor release): https://github.com/tannerlinsley/react-query/releases/tag/v3.6.0

I was using 3.12.0, but I think I had not rebuilt using webpack so perhaps it was just an issue due to that, it's working fine now... :)

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

2 participants