Skip to content

Commit

Permalink
fix(react): clear selections post-fetch in useQuery (#1594)
Browse files Browse the repository at this point in the history
  • Loading branch information
vicary committed Jul 29, 2023
1 parent aa8b66b commit 4eaf030
Show file tree
Hide file tree
Showing 16 changed files with 1,732 additions and 2,247 deletions.
4 changes: 0 additions & 4 deletions examples/gnt/.vscode/settings.json

This file was deleted.

5 changes: 3 additions & 2 deletions examples/gnt/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# GQty Next.js Template (GNT)

Created via `create-next-app` for Next v13 and React 18.
Created via `create-next-app` for Next 13 and React 18.

This is a playground for experimenting edge cases and behavior for `@gqty/react`, it doesn't serves a purpose of an example on it's own.
This is a playground for experimenting edge cases and behavior for
`@gqty/react`, it doesn't serves a purpose of an example on it's own.

Future examples will be born from the results of this playground.
35 changes: 23 additions & 12 deletions examples/gnt/app/MyComponent.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use client';

import { type FunctionComponent } from 'react';
import { useQuery } from '~/gqty';
import { useDeferredValue, useState, type FunctionComponent } from 'react';
import { useQuery } from '~/gqty/react';
import Avatar from './Avatar';
import Card from './Card';
import SmallText from './SmallText';
Expand All @@ -10,21 +10,32 @@ import Text from './Text';
export type Props = {};

const MyComponent: FunctionComponent<Props> = () => {
const [name, setName] = useState('Rick');
const deferredName = useDeferredValue(name);
const query = useQuery();

return (
<>
{query.characters()?.results?.map((character) => (
<Card key={character?.id ?? '0'}>
<Avatar character={character} />
<input
type="text"
defaultValue={name}
onChange={(e) => setName(e.target.value)}
className="border border-gray-300 rounded-md px-3 py-2 w-full text-black"
/>

<div className="flex-1">
<Text>{character?.name}</Text>
<SmallText>{character?.species}</SmallText>
<SmallText>{character?.origin?.name}</SmallText>
</div>
</Card>
))}
{query
.characters({ filter: { name: deferredName } })
?.results?.map((character) => (
<Card key={character?.id ?? '0'}>
<Avatar character={character} />

<div className="flex-1">
<Text>{character?.name}</Text>
<SmallText>{character?.species}</SmallText>
<SmallText>{character?.origin?.name}</SmallText>
</div>
</Card>
))}
</>
);
};
Expand Down
52 changes: 24 additions & 28 deletions examples/gnt/gqty/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@
* GQty: You can safely modify this file based on your needs.
*/

import { createReactClient } from '@gqty/react';
import type { QueryFetcher } from 'gqty';
import { Cache, createClient } from 'gqty';
import type { GeneratedSchema } from './schema.generated';
import { generatedSchema, scalarsEnumsHash } from './schema.generated';
import { Cache, GQtyError, createClient, type QueryFetcher } from 'gqty';
import {
generatedSchema,
scalarsEnumsHash,
type GeneratedSchema,
} from './schema.generated';

const queryFetcher: QueryFetcher = async function (
{ query, variables, operationName },
Expand All @@ -29,16 +30,30 @@ const queryFetcher: QueryFetcher = async function (
...fetchOptions,
});

const json = await response.json();
if (response.status >= 400) {
throw new GQtyError(
`GraphQL endpoint responded with HTTP ${response.status}: ${response.statusText}.`
);
}

const text = await response.text();

return json;
try {
return JSON.parse(text);
} catch {
throw new GQtyError(
`Malformed JSON response: ${
text.length > 50 ? text.slice(0, 50) + '...' : text
}`
);
}
};

const cache = new Cache(
undefined,
/**
* Default cache options immediate expiry with a 5 minutes window of
* stale-while-revalidate.
* Default option is immediate cache expiry but keep it for 5 minutes,
* allowing soft refetches in background.
*/
{
maxAge: 0,
Expand Down Expand Up @@ -70,23 +85,4 @@ export const {
track,
} = client;

export const {
graphql,
useQuery,
usePaginatedQuery,
useTransactionQuery,
useLazyQuery,
useRefetch,
useMutation,
useMetaState,
prepareReactRender,
useHydrateCache,
prepareQuery,
} = createReactClient<GeneratedSchema>(client, {
defaults: {
// Enable Suspense, you can override this option at hooks.
suspense: false,
},
});

export * from './schema.generated';
22 changes: 22 additions & 0 deletions examples/gnt/gqty/react.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { createReactClient } from '@gqty/react';
import { client } from '.';
import type { GeneratedSchema } from './schema.generated';

export const {
graphql,
useQuery,
usePaginatedQuery,
useTransactionQuery,
useLazyQuery,
useRefetch,
useMutation,
useMetaState,
prepareReactRender,
useHydrateCache,
prepareQuery,
} = createReactClient<GeneratedSchema>(client, {
defaults: {
// Enable Suspense, you can override this option at hooks.
suspense: false,
},
});
24 changes: 13 additions & 11 deletions examples/gnt/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,22 @@
"dependencies": {
"@gqty/logger": "workspace:^",
"@gqty/react": "workspace:^",
"autoprefixer": "10.4.14",
"gqty": "workspace:^",
"next": "^13.4.2",
"postcss": "8.4.21",
"graphql": "^16.7.1",
"next": "13.4.12",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"tailwindcss": "^3.3.2"
"react-dom": "^18.2.0"
},
"devDependencies": {
"@next/bundle-analyzer": "^13.4.2",
"@types/node": "18.15.11",
"@types/react": "^18.2.6",
"@types/react-dom": "^18.2.4",
"eslint": "^8.35.0",
"eslint-config-next": "13.3.0"
"@next/bundle-analyzer": "^13.4.12",
"@types/node": "20.4.5",
"@types/react": "18.2.17",
"@types/react-dom": "18.2.7",
"autoprefixer": "10.4.14",
"eslint": "8.46.0",
"eslint-config-next": "13.3.0",
"postcss": "8.4.21",
"tailwindcss": "^3.3.3",
"typescript": "^5.0.4"
}
}
2 changes: 1 addition & 1 deletion examples/gnt/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"jsx": "preserve",
"lib": ["dom", "dom.iterable", "esnext"],
"module": "esnext",
"moduleResolution": "node",
"moduleResolution": "bundler",
"noEmit": true,
"paths": { "~/*": ["./*"] },
"plugins": [{ "name": "next" }],
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
"chalk": "^5.2.0",
"changesets-github-release": "^0.1.0",
"concurrently": "^7.6.0",
"esbuild": "^0.17.19",
"esbuild": "^0.18.17",
"globby": "^13.1.3",
"husky": "^8.0.3",
"jest": "^29.5.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/gqty/src/Utils/hash.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ import objectHash from 'object-hash';
* Memoized hash function, with a prefix to avoid starting with a number.
*/
export const hash = memoize((...args: unknown[]) =>
objectHash(args).replace(/^(\d)/, 'a$1')
objectHash(args, { unorderedObjects: false }).replace(/^(\d)/, 'a$1')
);
2 changes: 1 addition & 1 deletion packages/gqty/test/accessor.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { getArrayFields, GQtyError } from '../src';
import { $meta, assignSelections, setCache } from '../src/Accessor';
import { createTestClient, Dog, expectConsoleWarn } from './utils';
import { createTestClient, expectConsoleWarn, type Dog } from './utils';

test('legacy warning', async () => {
const { query } = await createTestClient();
Expand Down
8 changes: 4 additions & 4 deletions packages/react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@
"sideEffects": false,
"exports": {
".": {
"require": "./dist/index.js",
"import": "./dist/index.mjs"
"import": "./dist/index.mjs",
"require": "./dist/index.js"
},
"./*": {
"require": "./dist/*.js",
"import": "./dist/*.mjs"
"import": "./dist/*.mjs",
"require": "./dist/*.js"
}
},
"main": "dist/index.js",
Expand Down
2 changes: 1 addition & 1 deletion packages/react/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ export type {
} from './mutation/useMutation';
export type { GraphQLHOC, GraphQLHOCOptions } from './query/hoc';
export type {
PreparedQuery,
PrepareQuery,
PreparedQuery,
UsePreparedQueryOptions,
} from './query/preparedQuery';
export type {
Expand Down
2 changes: 2 additions & 0 deletions packages/react/src/query/useQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,8 @@ export const createUseQuery = <TSchema extends BaseGeneratedSchema>(
context.notifyCacheUpdate = cachePolicy !== 'default';
state.promise = undefined;

selections.clear();

setState({});
}
},
Expand Down
4 changes: 1 addition & 3 deletions packages/react/test/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,8 @@
"declaration": false,
"esModuleInterop": true,
"jsx": "react",
"module": "commonjs",
"noEmit": true,
"strict": true,
"target": "es2019"
"strict": true
},
"exclude": [],
"include": ["**/*.ts", "**/*.tsx"]
Expand Down
44 changes: 20 additions & 24 deletions packages/react/test/useMutation.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ describe('useMutation', () => {
return useMutation((mutation, { name }: { name: string }) => {
const human = mutation.humanMutation({ nameArg: name });

human?.id;
human?.name;
return {
id: human.id,
name: human.name,
};
});
});

Expand All @@ -20,13 +22,8 @@ describe('useMutation', () => {
expect(result.current[1]).toMatchInlineSnapshot(`
{
"data": {
"mutation": {
"a75a2": {
"__typename": "Human",
"id": "1",
"name": "John Doe",
},
},
"id": "1",
"name": "John Doe",
},
"error": undefined,
"isLoading": false,
Expand All @@ -41,8 +38,10 @@ describe('useMutation', () => {
(mutation, { name }: { name: string }) => {
const human = mutation.humanMutation({ nameArg: name });

human?.id;
human?.name;
return {
id: human.id,
name: human.name,
};
},
{ suspense: true }
);
Expand All @@ -55,13 +54,8 @@ describe('useMutation', () => {
expect(result.current[1]).toMatchInlineSnapshot(`
{
"data": {
"mutation": {
"ba497": {
"__typename": "Human",
"id": "1",
"name": "Jane Doe",
},
},
"id": "1",
"name": "Jane Doe",
},
"error": undefined,
"isLoading": false,
Expand All @@ -74,19 +68,21 @@ describe('useMutation', () => {
const q = renderHook(() => {
const human = useQuery().human({ name: 'Uno' });

human.id;
human.name;

return human;
return {
id: human.id,
name: human.name,
};
});

const m = renderHook(() => {
return useMutation(
(mutation, args: { name: string; newName: string }) => {
const human = mutation.renameHuman(args);

human?.id;
human?.name;
return {
id: human.id,
name: human.name,
};
}
);
});
Expand Down
Loading

0 comments on commit 4eaf030

Please sign in to comment.