diff --git a/README.md b/README.md index c76cb05..7f47224 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,3 @@ - -## Description - -This is a simple Create React App demonstrating a bug (or potentially expected behavior) where unmounting a component that -has a "fetchPolicy" of "cache-and-network" and "nextFetchPolicy" of "cache-first" essentially resets the fetchPolicy state, -such that returning to the component utilizes the "fetchPolicy" rather than the "nextFetchPolicy", which means the query will -re-fire even though the data exists in cache. - -The way I work around this is wrapping my useQuery utilization and keeping a global tracker of whether the query has been run -once. If it has, I force the fetchPolicy to be "cache-first", this feels like a hack and I wonder if this behavior is expected -or is a bug w/Apollo. - ## Duplicating ```sh @@ -17,6 +5,9 @@ npm install npm run start ``` -1. Click "Click me to unmount to another route" -2. Click "Click me to go back to home and see the query re-fire" -3. You'll see the "loading.." indicator, which indicates the query has re-fired. \ No newline at end of file +1. Navigate to localhost:3000/124891248912491 +2. Notice that you will see an error from "useQuery", this is expected. +3. Click the button to return home where there is no movie query parameter. +4. Click the button to navigate to valid movie. +5. Note a flicker where the error message will temporarily render, and note in the console that the error is still present from the "useQuery" return value. +6. The error then disappears once the fetch is complete. However, since the variable set is distinct at the point of #4, the "useQuery" state should be empty and there should be no cached value for this query yet. \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 2e64c52..61726ad 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,23 +5,55 @@ "requires": true, "dependencies": { "@apollo/client": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/@apollo/client/-/client-3.2.5.tgz", - "integrity": "sha512-zpruxnFMz6K94gs2pqc3sidzFDbQpKT5D6P/J/I9s8ekHZ5eczgnRp6pqXC86Bh7+44j/btpmOT0kwiboyqTnA==", + "version": "3.3.20", + "resolved": "https://registry.npmjs.org/@apollo/client/-/client-3.3.20.tgz", + "integrity": "sha512-hS7UmBwJweudw/J3M0RAcusMHNiRuGqkRH6g91PM2ev8cXScIMdXr/++9jo7wD1nAITMCMF4HQQ3LFaw/Or0Bw==", "requires": { "@graphql-typed-document-node/core": "^3.0.0", "@types/zen-observable": "^0.8.0", - "@wry/context": "^0.5.2", - "@wry/equality": "^0.2.0", + "@wry/context": "^0.6.0", + "@wry/equality": "^0.5.0", "fast-json-stable-stringify": "^2.0.0", - "graphql-tag": "^2.11.0", + "graphql-tag": "^2.12.0", "hoist-non-react-statics": "^3.3.2", - "optimism": "^0.13.0", + "optimism": "^0.16.0", "prop-types": "^15.7.2", - "symbol-observable": "^2.0.0", - "ts-invariant": "^0.4.4", + "symbol-observable": "^4.0.0", + "ts-invariant": "^0.7.0", "tslib": "^1.10.0", "zen-observable": "^0.8.14" + }, + "dependencies": { + "graphql-tag": { + "version": "2.12.5", + "resolved": "https://registry.npmjs.org/graphql-tag/-/graphql-tag-2.12.5.tgz", + "integrity": "sha512-5xNhP4063d16Pz3HBtKprutsPrmHZi5IdUGOWRxA2B6VF7BIRGOHZ5WQvDmJXZuPcBg7rYwaFxvQYjqkSdR3TQ==", + "requires": { + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", + "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==" + } + } + }, + "ts-invariant": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/ts-invariant/-/ts-invariant-0.7.5.tgz", + "integrity": "sha512-qfVyqTYWEqADMtncLqwpUdMjMSXnsqOeqGtj1LeJNFDjz8oqZ1YxLEp29YCOq65z0LgEiERqQ8ThVjnfibJNpg==", + "requires": { + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", + "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==" + } + } + } } }, "@apollo/protobufjs": { @@ -3316,9 +3348,9 @@ "integrity": "sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw==" }, "@types/zen-observable": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@types/zen-observable/-/zen-observable-0.8.1.tgz", - "integrity": "sha512-wmk0xQI6Yy7Fs/il4EpOcflG4uonUpYGqvZARESLc2oy4u69fkatFLbJOeW4Q6awO15P4rduAe6xkwHevpXcUQ==" + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/@types/zen-observable/-/zen-observable-0.8.2.tgz", + "integrity": "sha512-HrCIVMLjE1MOozVoD86622S7aunluLb2PJdPfb3nYiEtohm8mIB/vyv0Fd37AdeMFrTUQXEunw78YloMA3Qilg==" }, "@typescript-eslint/eslint-plugin": { "version": "4.7.0", @@ -3568,19 +3600,48 @@ } }, "@wry/context": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/@wry/context/-/context-0.5.2.tgz", - "integrity": "sha512-B/JLuRZ/vbEKHRUiGj6xiMojST1kHhu4WcreLfNN7q9DqQFrb97cWgf/kiYsPSUCAMVN0HzfFc8XjJdzgZzfjw==", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@wry/context/-/context-0.6.0.tgz", + "integrity": "sha512-sAgendOXR8dM7stJw3FusRxFHF/ZinU0lffsA2YTyyIOfic86JX02qlPqPVqJNZJPAxFt+2EE8bvq6ZlS0Kf+Q==", "requires": { - "tslib": "^1.9.3" + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", + "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==" + } } }, "@wry/equality": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@wry/equality/-/equality-0.2.0.tgz", - "integrity": "sha512-Y4d+WH6hs+KZJUC8YKLYGarjGekBrhslDbf/R20oV+AakHPINSitHfDRQz3EGcEWc1luXYNUvMhawWtZVWNGvQ==", + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@wry/equality/-/equality-0.5.1.tgz", + "integrity": "sha512-FZKbdpbcVcbDxQrKcaBClNsQaMg9nof1RKM7mReJe5DKUzM5u8S7T+PqwNqvib5O2j2xxF1R4p5O3+b6baTrbw==", "requires": { - "tslib": "^1.9.3" + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", + "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==" + } + } + }, + "@wry/trie": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@wry/trie/-/trie-0.3.0.tgz", + "integrity": "sha512-Yw1akIogPhAT6XPYsRHlZZIS0tIGmAl9EYXHi2scf7LPKKqdqmow/Hu4kEqP2cJR3EjaU/9L0ZlAjFf3hFxmug==", + "requires": { + "tslib": "^2.1.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", + "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==" + } } }, "@xtuc/ieee754": { @@ -12378,11 +12439,12 @@ } }, "optimism": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/optimism/-/optimism-0.13.0.tgz", - "integrity": "sha512-6JAh3dH+YUE4QUdsgUw8nUQyrNeBKfAEKOHMlLkQ168KhIYFIxzPsHakWrRXDnTO+x61RJrS3/2uEt6W0xlocA==", + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/optimism/-/optimism-0.16.1.tgz", + "integrity": "sha512-64i+Uw3otrndfq5kaoGNoY7pvOhSsjFEN4bdEFh80MWVk/dbgJfMv7VFDeCT8LxNAlEVhQmdVEbfE7X2nWNIIg==", "requires": { - "@wry/context": "^0.5.2" + "@wry/context": "^0.6.0", + "@wry/trie": "^0.3.0" } }, "optimize-css-assets-webpack-plugin": { @@ -16529,9 +16591,9 @@ } }, "symbol-observable": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-2.0.3.tgz", - "integrity": "sha512-sQV7phh2WCYAn81oAkakC5qjq2Ml0g8ozqz03wOGnx9dDlG1de6yrF+0RAzSJD8fPUow3PTSMf2SAbOGxb93BA==" + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-4.0.0.tgz", + "integrity": "sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ==" }, "symbol-tree": { "version": "3.2.4", diff --git a/package.json b/package.json index dbb0113..85e3ff3 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "version": "0.1.0", "private": true, "dependencies": { - "@apollo/client": "^3.2.5", + "@apollo/client": "^3.3.20", "@testing-library/jest-dom": "^5.11.5", "@testing-library/react": "^11.1.2", "@testing-library/user-event": "^12.2.2", diff --git a/server.js b/server.js index c23ad70..ed644c2 100644 --- a/server.js +++ b/server.js @@ -1,22 +1,16 @@ const { ApolloServer, gql } = require('apollo-server-express'); const express = require('express'); -const { v4 } = require('uuid'); const simpleSchema = gql` type Query { - movies(movieIds: [Int!]): [Movie!]! - requestDetails: RequestDetails! + movie(movieId: ID!): Movie } type Movie { movieId: Int! internalTitle: String! } - - type RequestDetails { - id: String! - } `; const fakeMovies = { @@ -37,8 +31,8 @@ const fakeMovies = { internalTitle: 'some movie 80229867', }, 80025678: { - movieId: 80229867, - internalTitle: 'some movie 80229867', + movieId: 80025678, + internalTitle: 'some movie 80025678', }, 80229865:{ movieId: 80229865, @@ -70,15 +64,16 @@ const server = new ApolloServer({ typeDefs: simpleSchema.loc.source.body, resolvers: { Query: { - movies: (root, args, context, info) => { - const movieIds = args.movieIds; - return new Promise(resolve => { - setTimeout(() => { - resolve(movieIds.map(movieId => fakeMovies[movieId])); - }, 2000); + movie: (root, args, context, info) => { + return new Promise((resolve, reject) => { + if (fakeMovies[args.movieId]) { + resolve(fakeMovies[args.movieId]); + return; + } + reject('Unauthorized access'); }); }, - }, + } } }); const app = express(); diff --git a/src/index.tsx b/src/index.tsx index e2c4270..6e167c1 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,70 +1,70 @@ -import React from "react"; +import React, { useCallback } from "react"; import ReactDOM from "react-dom"; import gql from "graphql-tag"; -import { BrowserRouter, Link, Route, Switch } from 'react-router-dom'; +import { BrowserRouter, Route, Switch, useHistory, useParams } from 'react-router-dom'; import { ApolloClient, HttpLink, InMemoryCache, ApolloProvider, useQuery} from "@apollo/client"; - const client = new ApolloClient({ cache: new InMemoryCache(), link: new HttpLink({ uri: "/graphql" }), - defaultOptions: { - watchQuery: { - fetchPolicy: 'cache-and-network', - nextFetchPolicy: 'cache-first', - } - } }); -// Removing "requestDetails" from here will make the React warnings go away. -const GET_MOVIES = gql(` -query GetMovies($movieIds: [Int!]!) { - movies(movieIds: $movieIds) { +const GET_MOVIE = gql(` +query GetMovie($movieId: ID!) { + movie(movieId: $movieId) { movieId internalTitle } } `); -function FooBarPage() { - return