Open sheaosaurus opened 4 years ago
To update this ticket, my team and I did a debugging session today and found that the cause for the re-rendering was React.StrictMode.
A brief background for anyone reading this who is not aware, React.StrictMode, which runs in development mode only, intentionally double renders the application to check for legacy code, unwanted side-effects, etc. React.StrictMode Docs
StrictMode Enabled: Our Data component renders 6-8 times with the correct data, as described in the actual outcome in the OP.
StrictMode Not-Enabled: In development mode, the Data component renders 2 times with no data, while the filter component renders twice and correctly receives its filter.
The high level implications of this are that any code we tested and expect to work in dev will break in production.
Updated Intended Outcome
With React.StrictMode not enabled, I expect the data returned from the server to be on the data object in the component. From the picture below, the data is returned from the server and placed on the Root.Query object.
How to Reproduce
Please see updated Codesandbox with React.StrictMode removed: https://codesandbox.io/s/apollo-local-state-export-fields-strict-mode-disabled-rqmn1?file=/src/App.js
I just discovered this quirk today as well. Basically the double-rendering causes Apollo to create duplicate watched queries, so over time while using the application, the number of watched queries grows unbounded, and if you're using something like polling for example, because of the duplicate queries the server will be polled increasingly more frequently. I thought this was a bug in my code but realized it's just affecting development mode. Anyway long story short I've stopped using React.StrictMode
so that Apollo queries behave similarly in dev and prod environments.
My team and I are trying to migrate our filter state from Redux to Apollo Local State. This filter state needs to be added as a variable to the server queries, and we were hoping to use @export to achieve this.
In our app, on mount, the following queries need to be resolved:
const GET_POKEMON_TYPE_FILTER = gql
query { pokemonType @client } `;const GET_POKEMON = gql
query($name: String, $pokemonType: String) { pokemonName @client @export(as: "name") pokemonType @client @export(as: "pokemonType") pokemon(name: $name, pokemonType: $pokemonType) { id number name } }
;