Skip to content

Commit 5b9cd2d

Browse files
committed
deprecate memo (is a bug), create client on provider render, unset on unmount
1 parent c338720 commit 5b9cd2d

2 files changed

Lines changed: 78 additions & 82 deletions

File tree

packages/js/react/src/__tests__/useWeb3ApiQuery.spec.tsx

Lines changed: 59 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
renderHook,
1010
act,
1111
RenderHookOptions,
12+
cleanup
1213
} from "@testing-library/react-hooks";
1314
import {
1415
Uri,
@@ -28,7 +29,6 @@ describe("useWeb3ApiQuery hook", () => {
2829
let uri: Uri;
2930
let redirects: UriRedirect[];
3031
let WrapperProvider: RenderHookOptions<unknown>;
31-
let contractAddress: string;
3232

3333
beforeAll(async () => {
3434
const {
@@ -57,109 +57,75 @@ describe("useWeb3ApiQuery hook", () => {
5757
await stopTestEnvironment();
5858
});
5959

60-
const assertMutationWorks = async (
61-
options: QueryApiOptions,
62-
expectedResult: number
60+
const sendQuery = async (
61+
options: QueryApiOptions
6362
) => {
64-
const setDataStorageHook = () => useWeb3ApiQuery(options);
63+
const hook = () => useWeb3ApiQuery(options);
6564

66-
const {
67-
result: seStorageData,
68-
waitForNextUpdate: waitForDataStorageUpdate,
69-
} = renderHook(setDataStorageHook, WrapperProvider);
65+
const { result: hookResult } = renderHook(hook, WrapperProvider);
7066

71-
act(() => {
72-
seStorageData.current.execute();
67+
await act(async () => {
68+
await hookResult.current.execute();
7369
});
7470

75-
await waitForDataStorageUpdate();
76-
77-
const newResult = await queryStorageData(contractAddress, uri);
78-
expect(newResult).toBe(expectedResult);
79-
};
71+
const result = hookResult.current;
72+
cleanup();
73+
return result;
74+
}
8075

81-
const queryStorageData = async (contract: string, uri: Uri) => {
82-
const getStorageDataQuery: UseWeb3ApiQueryProps = {
83-
uri,
84-
query: `query {
85-
getData(
86-
address: "${contract}"
87-
)
88-
}`,
89-
};
90-
91-
const getDataStorageHook = () => useWeb3ApiQuery(getStorageDataQuery);
92-
93-
const {
94-
result: storageData,
95-
waitForNextUpdate: waitForDataStorage,
96-
} = renderHook(getDataStorageHook, WrapperProvider);
97-
98-
act(() => {
99-
storageData.current.execute();
100-
});
101-
102-
await waitForDataStorage();
103-
return storageData.current.data?.getData;
104-
};
105-
106-
it("Deployment should work", async () => {
76+
it("Should update storage data to five with hard coded value", async () => {
10777
const deployQuery: UseWeb3ApiQueryProps = {
10878
uri,
10979
query: `mutation { deployContract }`,
11080
};
11181

112-
const deployContractHook = () => useWeb3ApiQuery(deployQuery);
113-
114-
const {
115-
result: deployContractResult,
116-
waitForNextUpdate: waitForContractDeployment,
117-
} = renderHook(deployContractHook, WrapperProvider);
118-
119-
// assert initial state
120-
expect(deployContractResult.current.data).toBe(undefined);
121-
expect(deployContractResult.current.errors).toBe(undefined);
122-
expect(deployContractResult.current.loading).toBe(false);
123-
124-
// deploy contract
125-
act(() => {
126-
deployContractResult.current.execute();
127-
});
128-
129-
await waitForContractDeployment();
130-
contractAddress = deployContractResult.current.data
131-
?.deployContract as string;
132-
expect(deployContractResult.current.data?.deployContract).toMatch(/0x/);
133-
});
134-
135-
it("Should retrieve initial storage data which is 0 ", async () => {
136-
const data = await queryStorageData(contractAddress, uri);
137-
expect(data).toBe(0);
138-
});
82+
const { data } = await sendQuery(deployQuery);
13983

140-
it("Should update storage data to five with hard coded value", async () => {
14184
const setStorageDataQuery: UseWeb3ApiQueryProps = {
14285
uri,
14386
query: `
14487
mutation {
14588
setData(
146-
address: "${contractAddress}"
89+
address: "${data.deployContract}"
14790
value: 5
14891
)
14992
}
15093
`,
15194
};
15295

153-
await assertMutationWorks(setStorageDataQuery, 5);
96+
const result = await sendQuery(setStorageDataQuery);
97+
expect(result.errors).toBeFalsy();
98+
expect(result.data?.setData).toMatch(/0x/);
99+
100+
const getStorageDataQuery: UseWeb3ApiQueryProps = {
101+
uri,
102+
query: `
103+
query {
104+
getData(
105+
address: "${data.deployContract}"
106+
)
107+
}
108+
`,
109+
};
110+
111+
const { data: { getData } } = await sendQuery(getStorageDataQuery);
112+
expect(getData).toBe(5);
154113
});
155114

156-
it("Should update storage data to five by setting value through ", async () => {
115+
it("Should update storage data to five by setting value through variables", async () => {
116+
const deployQuery: UseWeb3ApiQueryProps = {
117+
uri,
118+
query: `mutation { deployContract }`,
119+
};
120+
121+
const { data } = await sendQuery(deployQuery);
122+
157123
const setStorageDataQuery: UseWeb3ApiQueryProps = {
158124
uri,
159125
query: `
160126
mutation {
161127
setData(
162-
address: "${contractAddress}"
128+
address: "${data.deployContract}"
163129
value: $value
164130
)
165131
}
@@ -169,7 +135,23 @@ describe("useWeb3ApiQuery hook", () => {
169135
},
170136
};
171137

172-
await assertMutationWorks(setStorageDataQuery, 5);
138+
const result = await sendQuery(setStorageDataQuery);
139+
expect(result.errors).toBeFalsy();
140+
expect(result.data?.setData).toMatch(/0x/);
141+
142+
const getStorageDataQuery: UseWeb3ApiQueryProps = {
143+
uri,
144+
query: `
145+
query {
146+
getData(
147+
address: "${data.deployContract}"
148+
)
149+
}
150+
`,
151+
};
152+
153+
const { data: { getData } } = await sendQuery(getStorageDataQuery);
154+
expect(getData).toBe(5);
173155
});
174156

175157
it("Should throw error because there's no provider with expected key ", async () => {
@@ -178,7 +160,7 @@ describe("useWeb3ApiQuery hook", () => {
178160
uri,
179161
query: `query {
180162
getData(
181-
address: "${contractAddress}"
163+
address: "foo"
182164
)
183165
}`,
184166
};
@@ -199,7 +181,7 @@ describe("useWeb3ApiQuery hook", () => {
199181
uri,
200182
query: `query {
201183
getData(
202-
address: "${contractAddress}"
184+
address: "foo"
203185
)
204186
}`,
205187
};

packages/js/react/src/provider.tsx

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ type ClientContext = React.Context<Web3ApiClient>
55

66
interface Web3ApiProviderState {
77
ClientContext: ClientContext;
8+
client?: Web3ApiClient;
89
}
910

1011
interface Web3ApiProviderMap {
@@ -35,16 +36,29 @@ export function createWeb3ApiProvider(
3536
};
3637

3738
return ({ redirects, children }) => {
38-
// Only recreate the Web3ApiClient when the redirects change
39-
const client = React.useMemo(
40-
() => new Web3ApiClient({ redirects }),
41-
[redirects]);
39+
// If the client has already been set for this provider
40+
if (PROVIDERS[name].client) {
41+
throw Error(
42+
`Duplicate Web3ApiProvider detected. Please use "createWeb3ApiProvider("provider-name")".`
43+
);
44+
}
45+
46+
// Instantiate the client
47+
PROVIDERS[name].client = new Web3ApiClient({ redirects });
48+
49+
// Unset the client in the global state when
50+
// this provider is unmounted
51+
React.useEffect(() => {
52+
return function cleanup() {
53+
PROVIDERS[name].client = undefined;
54+
}
55+
});
4256

4357
// Get the provider's context
4458
const ClientProvider = PROVIDERS[name].ClientContext.Provider;
4559

4660
return (
47-
<ClientProvider value={client}>
61+
<ClientProvider value={PROVIDERS[name].client as Web3ApiClient}>
4862
{children}
4963
</ClientProvider>
5064
);

0 commit comments

Comments
 (0)