async-fetch 0.3.4 → 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 CHANGED
@@ -4,8 +4,8 @@ Use async fetch hook for requests within React components.
4
4
 
5
5
  ## Installation
6
6
 
7
- ```
8
- $ npm i async-fetch
7
+ ```console
8
+ npm i async-fetch
9
9
  ```
10
10
 
11
11
  ## Usage
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "async-fetch",
3
- "version": "0.3.4",
3
+ "version": "0.3.5",
4
4
  "description": "Use async fetch hook for requests within React components.",
5
5
  "main": "useAsyncFetch.js",
6
6
  "type": "module",
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: data2,
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,126 +32,111 @@ function useAsyncFetch(stringUrl, props = {}) {
32
32
 
33
33
  const [cancelSource, setCancelSource] = useState();
34
34
 
35
- const [unmounted, setUnmounted] = useState(false);
36
-
37
- useEffect(() => {
38
- return cleanupRequest;
39
- }, []);
40
-
41
- useEffect(() => {
42
- sendRequest();
43
- }, [stringUrl, ...deps]);
44
-
45
- useInterval(() => {
46
- sendRequest();
47
- }, poll);
48
-
49
- function cancelRequest() {
35
+ const cancelRequest = useCallback(() => {
50
36
  if (cancelSource?.abort) cancelSource.abort();
51
- }
52
-
53
- function cleanupRequest() {
54
- if (ignoreCleanup !== true) {
55
- setUnmounted(true);
56
- cancelRequest();
57
- }
58
- }
37
+ }, [cancelSource]);
59
38
 
60
- async function sendRequest() {
61
- if (!stringUrl) {
62
- throw new Error("URL is required.");
63
- }
64
-
65
- if (typeof stringUrl !== "string") {
66
- throw new Error("URL must be of type string.");
67
- }
39
+ const sendRequest = useCallback(async () => {
40
+ if (ignoreRequest === true) return;
68
41
 
69
42
  const url = new URL(stringUrl, window.location.origin);
70
43
 
71
- if (ignoreRequest !== true) {
72
- const controller = new AbortController();
44
+ if (query || params) url.search = new URLSearchParams(query || params);
73
45
 
74
- fetchProps.signal = controller.signal;
46
+ const contentType =
47
+ fetchProps.headers?.["Content-Type"] ||
48
+ fetchProps.headers?.["content-type"];
75
49
 
76
- const requestTimeout = setTimeout(() => {
77
- controller.abort();
78
- }, timeout);
79
-
80
- try {
81
- if (query || params) url.search = new URLSearchParams(query || params);
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
+ }
82
55
 
83
- const contentType =
84
- fetchProps.headers?.["Content-Type"] ||
85
- fetchProps.headers?.["content-type"];
56
+ const controller = new AbortController();
86
57
 
87
- if (contentType === "application/x-www-form-urlencoded") {
88
- fetchProps.body = new URLSearchParams(data2 || {});
89
- } else if (data2) {
90
- fetchProps.body = JSON.stringify(data2);
91
- }
58
+ const requestTimeout = setTimeout(() => controller.abort(), timeout);
92
59
 
93
- if (!unmounted) {
94
- if (pending) setPending2(true);
60
+ fetchProps.signal = controller.signal;
95
61
 
96
- if (!pending) setPending(true);
62
+ if (pending) setPending2(true);
97
63
 
98
- setError();
64
+ if (!pending) setPending(true);
99
65
 
100
- cancelRequest();
66
+ setError();
101
67
 
102
- setCancelSource(controller);
68
+ cancelRequest();
103
69
 
104
- if (onStart) onStart();
105
- }
70
+ setCancelSource(controller);
106
71
 
107
- const response = await fetch(url, fetchProps);
72
+ if (onStart) onStart();
108
73
 
109
- if (!response.ok) {
110
- throw new Error(
111
- JSON.stringify({
112
- code: response.status,
113
- text: response.statusText,
114
- response: await response.text(),
115
- }),
116
- );
117
- }
74
+ try {
75
+ const response = await fetch(url, fetchProps);
118
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 {
119
86
  const parsedResponse = await response[parser]();
120
87
 
121
- if (!unmounted) {
122
- setData(parsedResponse);
88
+ setData(parsedResponse);
123
89
 
124
- if (onSuccess) onSuccess(parsedResponse);
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() };
125
99
  }
126
- } catch (e) {
127
- if (!unmounted && e.name !== "AbortError") {
128
- let error;
129
-
130
- try {
131
- error = JSON.parse(e.toString().replace("Error:", "").trim());
132
- } catch {
133
- error = { response: e.toString(), text: e.toString() };
134
- }
135
-
136
- setError(error);
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
+ ]);
137
126
 
138
- if (onFail) onFail(error);
139
- }
140
- } finally {
141
- clearTimeout(requestTimeout);
127
+ useEffect(() => {
128
+ sendRequest();
129
+ }, deps);
142
130
 
143
- if (!unmounted) {
144
- if (pending) {
145
- setPending2();
146
- } else {
147
- setPending();
148
- }
131
+ useInterval(() => {
132
+ sendRequest();
133
+ }, poll);
149
134
 
150
- if (onFinish) onFinish();
151
- }
152
- }
153
- }
154
- }
135
+ useEffect(() => {
136
+ return () => {
137
+ if (ignoreCleanup !== true) cancelRequest();
138
+ };
139
+ }, []);
155
140
 
156
141
  return {
157
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 < 1000) return;
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