async-fetch 0.3.3 → 0.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/package.json +1 -1
- package/useAsyncFetch.js +84 -95
- package/useInterval.js +4 -6
package/README.md
CHANGED
package/package.json
CHANGED
package/useAsyncFetch.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useState, useEffect } from "react";
|
|
1
|
+
import { useState, useCallback, useEffect } from "react";
|
|
2
2
|
import useInterval from "./useInterval.js";
|
|
3
3
|
|
|
4
4
|
function useAsyncFetch(stringUrl, props = {}) {
|
|
@@ -9,11 +9,11 @@ function useAsyncFetch(stringUrl, props = {}) {
|
|
|
9
9
|
deps = [],
|
|
10
10
|
poll,
|
|
11
11
|
timeout = 30000, // 30 seconds.
|
|
12
|
-
ignoreCleanup,
|
|
13
12
|
ignoreRequest,
|
|
13
|
+
ignoreCleanup,
|
|
14
14
|
query,
|
|
15
15
|
params,
|
|
16
|
-
data:
|
|
16
|
+
data: body,
|
|
17
17
|
parser = "json",
|
|
18
18
|
onStart,
|
|
19
19
|
onSuccess,
|
|
@@ -24,7 +24,7 @@ function useAsyncFetch(stringUrl, props = {}) {
|
|
|
24
24
|
|
|
25
25
|
const [pending, setPending] = useState(initialPending);
|
|
26
26
|
|
|
27
|
-
const [pending2, setPending2] = useState();
|
|
27
|
+
const [pending2, setPending2] = useState(initialPending);
|
|
28
28
|
|
|
29
29
|
const [data, setData] = useState(initialData);
|
|
30
30
|
|
|
@@ -32,122 +32,111 @@ function useAsyncFetch(stringUrl, props = {}) {
|
|
|
32
32
|
|
|
33
33
|
const [cancelSource, setCancelSource] = useState();
|
|
34
34
|
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
useEffect(() => {
|
|
38
|
-
return cleanupRequest;
|
|
39
|
-
}, []);
|
|
40
|
-
|
|
41
|
-
useEffect(sendRequest, [stringUrl, ...deps]);
|
|
42
|
-
|
|
43
|
-
useInterval(sendRequest, poll);
|
|
44
|
-
|
|
45
|
-
function cancelRequest() {
|
|
35
|
+
const cancelRequest = useCallback(() => {
|
|
46
36
|
if (cancelSource?.abort) cancelSource.abort();
|
|
47
|
-
}
|
|
37
|
+
}, [cancelSource]);
|
|
48
38
|
|
|
49
|
-
|
|
50
|
-
if (
|
|
51
|
-
setUnmounted(true);
|
|
52
|
-
cancelRequest();
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
async function sendRequest() {
|
|
57
|
-
if (!stringUrl) {
|
|
58
|
-
throw new Error("URL is required.");
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
if (typeof stringUrl !== "string") {
|
|
62
|
-
throw new Error("URL must be of type string.");
|
|
63
|
-
}
|
|
39
|
+
const sendRequest = useCallback(async () => {
|
|
40
|
+
if (ignoreRequest === true) return;
|
|
64
41
|
|
|
65
42
|
const url = new URL(stringUrl, window.location.origin);
|
|
66
43
|
|
|
67
|
-
if (
|
|
68
|
-
const controller = new AbortController();
|
|
44
|
+
if (query || params) url.search = new URLSearchParams(query || params);
|
|
69
45
|
|
|
70
|
-
|
|
46
|
+
const contentType =
|
|
47
|
+
fetchProps.headers?.["Content-Type"] ||
|
|
48
|
+
fetchProps.headers?.["content-type"];
|
|
71
49
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
50
|
+
if (contentType === "application/x-www-form-urlencoded") {
|
|
51
|
+
fetchProps.body = new URLSearchParams(body || {});
|
|
52
|
+
} else if (body) {
|
|
53
|
+
fetchProps.body = JSON.stringify(body);
|
|
54
|
+
}
|
|
75
55
|
|
|
76
|
-
|
|
77
|
-
if (query || params) url.search = new URLSearchParams(query || params);
|
|
56
|
+
const controller = new AbortController();
|
|
78
57
|
|
|
79
|
-
|
|
80
|
-
fetchProps.headers?.["Content-Type"] ||
|
|
81
|
-
fetchProps.headers?.["content-type"];
|
|
58
|
+
const requestTimeout = setTimeout(() => controller.abort(), timeout);
|
|
82
59
|
|
|
83
|
-
|
|
84
|
-
fetchProps.body = new URLSearchParams(data2 || {});
|
|
85
|
-
} else if (data2) {
|
|
86
|
-
fetchProps.body = JSON.stringify(data2);
|
|
87
|
-
}
|
|
60
|
+
fetchProps.signal = controller.signal;
|
|
88
61
|
|
|
89
|
-
|
|
90
|
-
if (pending) setPending2(true);
|
|
62
|
+
if (pending) setPending2(true);
|
|
91
63
|
|
|
92
|
-
|
|
64
|
+
if (!pending) setPending(true);
|
|
93
65
|
|
|
94
|
-
|
|
66
|
+
setError();
|
|
95
67
|
|
|
96
|
-
|
|
68
|
+
cancelRequest();
|
|
97
69
|
|
|
98
|
-
|
|
70
|
+
setCancelSource(controller);
|
|
99
71
|
|
|
100
|
-
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
const response = await fetch(url, fetchProps);
|
|
72
|
+
if (onStart) onStart();
|
|
104
73
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
JSON.stringify({
|
|
108
|
-
code: response.status,
|
|
109
|
-
text: response.statusText,
|
|
110
|
-
response: await response.text(),
|
|
111
|
-
}),
|
|
112
|
-
);
|
|
113
|
-
}
|
|
74
|
+
try {
|
|
75
|
+
const response = await fetch(url, fetchProps);
|
|
114
76
|
|
|
77
|
+
if (!response.ok) {
|
|
78
|
+
throw new Error(
|
|
79
|
+
JSON.stringify({
|
|
80
|
+
code: response.status,
|
|
81
|
+
text: response.statusText,
|
|
82
|
+
response: await response.text(),
|
|
83
|
+
}),
|
|
84
|
+
);
|
|
85
|
+
} else {
|
|
115
86
|
const parsedResponse = await response[parser]();
|
|
116
87
|
|
|
117
|
-
|
|
118
|
-
setData(parsedResponse);
|
|
88
|
+
setData(parsedResponse);
|
|
119
89
|
|
|
120
|
-
|
|
90
|
+
if (onSuccess) onSuccess(parsedResponse);
|
|
91
|
+
}
|
|
92
|
+
} catch (e) {
|
|
93
|
+
if (e.name !== "AbortError") {
|
|
94
|
+
let error;
|
|
95
|
+
try {
|
|
96
|
+
error = JSON.parse(e.toString().replace("Error:", "").trim());
|
|
97
|
+
} catch {
|
|
98
|
+
error = { response: e.toString(), text: e.toString() };
|
|
121
99
|
}
|
|
122
|
-
|
|
123
|
-
if (
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
100
|
+
setError(error);
|
|
101
|
+
if (onFail) onFail(error);
|
|
102
|
+
}
|
|
103
|
+
} finally {
|
|
104
|
+
clearTimeout(requestTimeout);
|
|
105
|
+
if (pending) {
|
|
106
|
+
setPending2();
|
|
107
|
+
} else {
|
|
108
|
+
setPending();
|
|
109
|
+
}
|
|
110
|
+
if (onFinish) onFinish();
|
|
111
|
+
}
|
|
112
|
+
}, [
|
|
113
|
+
ignoreRequest,
|
|
114
|
+
stringUrl,
|
|
115
|
+
query,
|
|
116
|
+
params,
|
|
117
|
+
fetchProps,
|
|
118
|
+
body,
|
|
119
|
+
timeout,
|
|
120
|
+
parser,
|
|
121
|
+
onStart,
|
|
122
|
+
onSuccess,
|
|
123
|
+
onFail,
|
|
124
|
+
onFinish,
|
|
125
|
+
]);
|
|
133
126
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
clearTimeout(requestTimeout);
|
|
127
|
+
useEffect(() => {
|
|
128
|
+
sendRequest();
|
|
129
|
+
}, deps);
|
|
138
130
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
} else {
|
|
143
|
-
setPending();
|
|
144
|
-
}
|
|
131
|
+
useInterval(() => {
|
|
132
|
+
sendRequest();
|
|
133
|
+
}, poll);
|
|
145
134
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
}
|
|
150
|
-
}
|
|
135
|
+
useEffect(() => {
|
|
136
|
+
return () => {
|
|
137
|
+
if (ignoreCleanup !== true) cancelRequest();
|
|
138
|
+
};
|
|
139
|
+
}, []);
|
|
151
140
|
|
|
152
141
|
return {
|
|
153
142
|
pending: pending || pending2,
|
package/useInterval.js
CHANGED
|
@@ -4,17 +4,15 @@ function useInterval(callback, poll) {
|
|
|
4
4
|
const callbackRef = useRef(() => {}); // noop
|
|
5
5
|
|
|
6
6
|
useEffect(() => {
|
|
7
|
-
callbackRef.current = callback;
|
|
8
|
-
});
|
|
7
|
+
if (typeof callback === "function") callbackRef.current = callback;
|
|
8
|
+
}, [callback]);
|
|
9
9
|
|
|
10
10
|
useEffect(() => {
|
|
11
|
-
if (typeof poll !== "number" || poll <
|
|
11
|
+
if (typeof poll !== "number" || poll < 100) return;
|
|
12
12
|
|
|
13
13
|
const interval = setInterval(() => callbackRef.current(), poll);
|
|
14
14
|
|
|
15
|
-
return () =>
|
|
16
|
-
clearInterval(interval);
|
|
17
|
-
};
|
|
15
|
+
return () => clearInterval(interval);
|
|
18
16
|
}, [poll]);
|
|
19
17
|
}
|
|
20
18
|
|