Skip to content

Commit ab6268d

Browse files
committed
Add useState to dispatcher
1 parent d259a21 commit ab6268d

File tree

1 file changed

+53
-56
lines changed

1 file changed

+53
-56
lines changed

src/useDispatcher.js

Lines changed: 53 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useContext, useRef } from 'react';
1+
import { useContext, useState, useRef } from 'react';
22
import TransporterContext from './TransporterContext';
33

44
const PENDING = 'pending';
@@ -20,67 +20,64 @@ export default function useDispatcher() {
2020
throw new Error('Dispatcher hook is used outside of TransporterContext.');
2121
}
2222

23+
const [state, setState] = useState({
24+
ok: null,
25+
loading: false,
26+
executed: false,
27+
error: null,
28+
});
29+
2330
const instances = useRef([]);
2431

25-
return {
26-
dispatch(ast, options) {
27-
const operation = ast.definitions.find(
28-
(def) => def.kind === 'OperationDefinition',
29-
)?.operation;
32+
const updateState = (instance) => {
33+
const latestInstance = getLatestInstance(instances);
34+
35+
if (latestInstance !== instance) {
36+
return;
37+
}
3038

31-
if (operation !== 'query' && operation !== 'mutation') {
32-
throw new Error(
33-
'No operation found. Must be either "query" or "mutation".',
34-
);
35-
}
39+
const { status } = instance.resource;
3640

37-
const instance =
38-
operation === 'query'
39-
? context.client.query(ast, options)
40-
: context.client.mutate(ast, options);
41+
setState({
42+
ok: status === PENDING ? null : status === FULFILLED,
43+
loading: status === PENDING,
44+
executed: status === FULFILLED || status === REJECTED,
45+
error: status !== REJECTED ? null : instance.resource.response,
46+
});
47+
};
4148

42-
instances.current.push(instance);
49+
const dispatch = (ast, options) => {
50+
const operation = ast.definitions.find(
51+
(def) => def.kind === 'OperationDefinition',
52+
)?.operation;
4353

44-
// Return cached selector set.
45-
return instance.resource.promise.then(() =>
46-
instance.cache.graphData.getQuery(),
54+
if (operation !== 'query' && operation !== 'mutation') {
55+
throw new Error(
56+
'No operation found. Must be either "query" or "mutation".',
4757
);
48-
},
49-
get ok() {
50-
const instance = getLatestInstance(instances);
51-
52-
if (!instance || instance.status === PENDING) {
53-
return null;
54-
}
55-
56-
return instance.status === FULFILLED;
57-
},
58-
get loading() {
59-
const instance = getLatestInstance(instances);
60-
61-
if (!instance) {
62-
return false;
63-
}
64-
65-
return instance.status === PENDING;
66-
},
67-
get executed() {
68-
const instance = getLatestInstance(instances);
69-
70-
if (!instance) {
71-
return false;
72-
}
73-
74-
return instance.status === FULFILLED || instance.status === REJECTED;
75-
},
76-
get error() {
77-
const instance = getLatestInstance(instances);
78-
79-
if (!instance || instance.status !== REJECTED) {
80-
return null;
81-
}
82-
83-
return instance.response;
84-
},
58+
}
59+
60+
const instance =
61+
operation === 'query'
62+
? context.client.query(ast, options)
63+
: context.client.mutate(ast, options);
64+
65+
instances.current.push(instance);
66+
67+
updateState(instance);
68+
69+
// Update state and return cached selector set.
70+
return instance.resource.promise.then(
71+
() => {
72+
updateState(instance);
73+
return instance.cache.graphData.getQuery();
74+
},
75+
(err) => {
76+
updateState(instance);
77+
throw err;
78+
},
79+
);
8580
};
81+
82+
return [dispatch, state];
8683
}

0 commit comments

Comments
 (0)