@ahoo-wang/fetcher-react 3.5.8 → 3.6.1
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 +868 -609
- package/README.zh-CN.md +2079 -672
- package/dist/core/debounced/index.d.ts +4 -0
- package/dist/core/debounced/index.d.ts.map +1 -0
- package/dist/core/debounced/useDebouncedCallback.d.ts.map +1 -0
- package/dist/core/{useDebouncedExecutePromise.d.ts → debounced/useDebouncedExecutePromise.d.ts} +1 -1
- package/dist/core/debounced/useDebouncedExecutePromise.d.ts.map +1 -0
- package/dist/{wow/debounce → core/debounced}/useDebouncedQuery.d.ts +1 -2
- package/dist/core/debounced/useDebouncedQuery.d.ts.map +1 -0
- package/dist/core/index.d.ts +3 -2
- package/dist/core/index.d.ts.map +1 -1
- package/dist/{wow → core}/useQuery.d.ts +3 -3
- package/dist/core/useQuery.d.ts.map +1 -0
- package/dist/{wow → core}/useQueryState.d.ts +2 -2
- package/dist/core/useQueryState.d.ts.map +1 -0
- package/dist/cosec/useSecurity.d.ts +1 -1
- package/dist/fetcher/debounced/index.d.ts +3 -0
- package/dist/fetcher/debounced/index.d.ts.map +1 -0
- package/dist/fetcher/{useDebouncedFetcher.d.ts → debounced/useDebouncedFetcher.d.ts} +2 -2
- package/dist/fetcher/debounced/useDebouncedFetcher.d.ts.map +1 -0
- package/dist/{wow/debounce → fetcher/debounced}/useDebouncedFetcherQuery.d.ts +1 -1
- package/dist/fetcher/debounced/useDebouncedFetcherQuery.d.ts.map +1 -0
- package/dist/fetcher/index.d.ts +2 -1
- package/dist/fetcher/index.d.ts.map +1 -1
- package/dist/{wow → fetcher}/useFetcherQuery.d.ts +4 -4
- package/dist/fetcher/useFetcherQuery.d.ts.map +1 -0
- package/dist/index.es.js +573 -552
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +1 -1
- package/dist/index.umd.js.map +1 -1
- package/dist/types.d.ts +7 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/wow/fetcher/index.d.ts +6 -0
- package/dist/wow/fetcher/index.d.ts.map +1 -0
- package/dist/wow/{useFetcherCountQuery.d.ts → fetcher/useFetcherCountQuery.d.ts} +2 -2
- package/dist/wow/fetcher/useFetcherCountQuery.d.ts.map +1 -0
- package/dist/wow/{useFetcherListQuery.d.ts → fetcher/useFetcherListQuery.d.ts} +2 -2
- package/dist/wow/fetcher/useFetcherListQuery.d.ts.map +1 -0
- package/dist/wow/{useFetcherListStreamQuery.d.ts → fetcher/useFetcherListStreamQuery.d.ts} +2 -2
- package/dist/wow/fetcher/useFetcherListStreamQuery.d.ts.map +1 -0
- package/dist/wow/{useFetcherPagedQuery.d.ts → fetcher/useFetcherPagedQuery.d.ts} +2 -2
- package/dist/wow/fetcher/useFetcherPagedQuery.d.ts.map +1 -0
- package/dist/wow/{useFetcherSingleQuery.d.ts → fetcher/useFetcherSingleQuery.d.ts} +2 -2
- package/dist/wow/fetcher/useFetcherSingleQuery.d.ts.map +1 -0
- package/dist/wow/index.d.ts +1 -10
- package/dist/wow/index.d.ts.map +1 -1
- package/dist/wow/useCountQuery.d.ts +1 -1
- package/dist/wow/useCountQuery.d.ts.map +1 -1
- package/dist/wow/useListQuery.d.ts +1 -1
- package/dist/wow/useListQuery.d.ts.map +1 -1
- package/dist/wow/useListStreamQuery.d.ts +1 -1
- package/dist/wow/useListStreamQuery.d.ts.map +1 -1
- package/dist/wow/usePagedQuery.d.ts +1 -1
- package/dist/wow/usePagedQuery.d.ts.map +1 -1
- package/dist/wow/useSingleQuery.d.ts +1 -1
- package/dist/wow/useSingleQuery.d.ts.map +1 -1
- package/package.json +2 -2
- package/dist/core/useDebouncedCallback.d.ts.map +0 -1
- package/dist/core/useDebouncedExecutePromise.d.ts.map +0 -1
- package/dist/fetcher/useDebouncedFetcher.d.ts.map +0 -1
- package/dist/wow/debounce/index.d.ts +0 -3
- package/dist/wow/debounce/index.d.ts.map +0 -1
- package/dist/wow/debounce/useDebouncedFetcherQuery.d.ts.map +0 -1
- package/dist/wow/debounce/useDebouncedQuery.d.ts.map +0 -1
- package/dist/wow/types.d.ts +0 -7
- package/dist/wow/types.d.ts.map +0 -1
- package/dist/wow/useFetcherCountQuery.d.ts.map +0 -1
- package/dist/wow/useFetcherListQuery.d.ts.map +0 -1
- package/dist/wow/useFetcherListStreamQuery.d.ts.map +0 -1
- package/dist/wow/useFetcherPagedQuery.d.ts.map +0 -1
- package/dist/wow/useFetcherQuery.d.ts.map +0 -1
- package/dist/wow/useFetcherSingleQuery.d.ts.map +0 -1
- package/dist/wow/useQuery.d.ts.map +0 -1
- package/dist/wow/useQueryState.d.ts.map +0 -1
- /package/dist/core/{useDebouncedCallback.d.ts → debounced/useDebouncedCallback.d.ts} +0 -0
package/README.md
CHANGED
|
@@ -29,19 +29,25 @@ robust data fetching capabilities.
|
|
|
29
29
|
- [Quick Start](#quick-start)
|
|
30
30
|
- [Usage](#usage)
|
|
31
31
|
- [Core Hooks](#core-hooks)
|
|
32
|
-
- [useFetcher](#usefetcher-hook)
|
|
33
32
|
- [useExecutePromise](#useexecutepromise-hook)
|
|
34
33
|
- [usePromiseState](#usepromisestate-hook)
|
|
35
|
-
- [Debounced Hooks](#debounced-hooks)
|
|
36
|
-
- [useDebouncedCallback](#usedebouncedcallback)
|
|
37
|
-
- [useDebouncedExecutePromise](#usedebouncedexecutepromise)
|
|
38
|
-
- [useDebouncedFetcher](#usedebouncedfetcher)
|
|
39
|
-
- [useDebouncedFetcherQuery](#usedebouncedfetcherquery)
|
|
40
|
-
- [useDebouncedQuery](#usedebouncedquery)
|
|
41
|
-
- [Utility Hooks](#utility-hooks)
|
|
42
34
|
- [useRequestId](#userequestid-hook)
|
|
43
35
|
- [useLatest](#uselatest-hook)
|
|
44
36
|
- [useRefs](#userefs-hook)
|
|
37
|
+
- [useQuery](#usequery-hook)
|
|
38
|
+
- [useQueryState](#usequerystate-hook)
|
|
39
|
+
- [useMounted](#usemounted-hook)
|
|
40
|
+
- [useForceUpdate](#useforceupdate-hook)
|
|
41
|
+
- [Debounced Hooks](#debounced-hooks)
|
|
42
|
+
- [useDebouncedCallback](#usedebouncedcallback)
|
|
43
|
+
- [useDebouncedExecutePromise](#usedebouncedexecutepromise)
|
|
44
|
+
- [useDebouncedQuery](#usedebouncedquery)
|
|
45
|
+
- [Fetcher Hooks](#fetcher-hooks)
|
|
46
|
+
- [useFetcher](#usefetcher-hook)
|
|
47
|
+
- [useFetcherQuery](#usefetcherquery-hook)
|
|
48
|
+
- [Debounced Fetcher Hooks](#debounced-fetcher-hooks)
|
|
49
|
+
- [useDebouncedFetcher](#usedebouncedfetcher)
|
|
50
|
+
- [useDebouncedFetcherQuery](#usedebouncedfetcherquery)
|
|
45
51
|
- [Storage Hooks](#storage-hooks)
|
|
46
52
|
- [useKeyStorage](#usekeystorage-hook)
|
|
47
53
|
- [useImmerKeyStorage](#useimmerkeystorage-hook)
|
|
@@ -51,20 +57,20 @@ robust data fetching capabilities.
|
|
|
51
57
|
- [useSecurity](#usesecurity-hook)
|
|
52
58
|
- [SecurityProvider](#securityprovider)
|
|
53
59
|
- [useSecurityContext](#usesecuritycontext-hook)
|
|
60
|
+
- [RouteGuard](#routeguard)
|
|
54
61
|
- [Wow Query Hooks](#wow-query-hooks)
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
- [
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
- [useFetcherListStreamQuery](#usefetcherliststreamquery-hook)
|
|
62
|
+
- [Basic Query Hooks](#basic-query-hooks)
|
|
63
|
+
- [useListQuery](#uselistquery-hook)
|
|
64
|
+
- [usePagedQuery](#usepagedquery-hook)
|
|
65
|
+
- [useSingleQuery](#usesinglequery-hook)
|
|
66
|
+
- [useCountQuery](#usecountquery-hook)
|
|
67
|
+
- [useListStreamQuery](#useliststreamquery-hook)
|
|
68
|
+
- [Fetcher Query Hooks](#fetcher-query-hooks)
|
|
69
|
+
- [useFetcherListQuery](#usefetcherlistquery-hook)
|
|
70
|
+
- [useFetcherPagedQuery](#usefetcherpagedquery-hook)
|
|
71
|
+
- [useFetcherSingleQuery](#usefetchersinglequery-hook)
|
|
72
|
+
- [useFetcherCountQuery](#usefetchercountquery-hook)
|
|
73
|
+
- [useFetcherListStreamQuery](#usefetcherliststreamquery-hook)
|
|
68
74
|
- [Best Practices](#best-practices)
|
|
69
75
|
- [API Reference](#api-reference)
|
|
70
76
|
- [License](#license)
|
|
@@ -107,269 +113,428 @@ function App() {
|
|
|
107
113
|
|
|
108
114
|
### Core Hooks
|
|
109
115
|
|
|
110
|
-
####
|
|
116
|
+
#### useExecutePromise Hook
|
|
111
117
|
|
|
112
|
-
The `
|
|
113
|
-
protection, and
|
|
118
|
+
The `useExecutePromise` hook manages asynchronous operations with automatic state handling, built-in race condition
|
|
119
|
+
protection, and support for promise state options. It includes automatic AbortController support for canceling operations.
|
|
114
120
|
|
|
115
121
|
```typescript jsx
|
|
116
|
-
import {
|
|
122
|
+
import { useExecutePromise } from '@ahoo-wang/fetcher-react';
|
|
117
123
|
|
|
118
124
|
const MyComponent = () => {
|
|
119
|
-
const { loading,
|
|
125
|
+
const { loading, result, error, execute, reset, abort } = useExecutePromise<string>({
|
|
120
126
|
onAbort: () => {
|
|
121
|
-
console.log('
|
|
127
|
+
console.log('Operation was aborted');
|
|
122
128
|
}
|
|
123
129
|
});
|
|
124
130
|
|
|
131
|
+
const fetchData = async () => {
|
|
132
|
+
const response = await fetch('/api/data');
|
|
133
|
+
return response.text();
|
|
134
|
+
};
|
|
135
|
+
|
|
125
136
|
const handleFetch = () => {
|
|
126
|
-
execute(
|
|
137
|
+
execute(fetchData); // Using a promise supplier
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
const handleDirectPromise = () => {
|
|
141
|
+
const promise = fetch('/api/data').then(res => res.text());
|
|
142
|
+
execute(promise); // Using a direct promise
|
|
127
143
|
};
|
|
128
144
|
|
|
129
145
|
const handleAbort = () => {
|
|
130
|
-
abort(); //
|
|
146
|
+
abort(); // Manually abort the current operation
|
|
131
147
|
};
|
|
148
|
+
|
|
149
|
+
if (loading) return <div>Loading...</div>;
|
|
150
|
+
if (error) return <div>Error: {error.message}</div>;
|
|
151
|
+
return (
|
|
152
|
+
<div>
|
|
153
|
+
<button onClick={handleFetch}>Fetch with Supplier</button>
|
|
154
|
+
<button onClick={handleDirectPromise}>Fetch with Promise</button>
|
|
155
|
+
<button onClick={handleAbort} disabled={!loading}>Abort</button>
|
|
156
|
+
<button onClick={reset}>Reset</button>
|
|
157
|
+
{result && <p>{result}</p>}
|
|
158
|
+
</div>
|
|
159
|
+
);
|
|
160
|
+
};
|
|
132
161
|
```
|
|
133
162
|
|
|
134
|
-
|
|
163
|
+
##### Abort Controller Support
|
|
164
|
+
|
|
165
|
+
The hook automatically creates an AbortController for each operation and provides methods to manage cancellation:
|
|
166
|
+
|
|
167
|
+
- **Automatic Cleanup**: Operations are automatically aborted when the component unmounts
|
|
168
|
+
- **Manual Abort**: Use the `abort()` method to cancel ongoing operations
|
|
169
|
+
- **onAbort Callback**: Configure a callback that fires when an operation is aborted (manually or automatically)
|
|
170
|
+
- **AbortController Access**: The AbortController is passed to promise suppliers for advanced cancellation handling
|
|
171
|
+
|
|
172
|
+
#### usePromiseState Hook
|
|
173
|
+
|
|
174
|
+
The `usePromiseState` hook provides state management for promise operations without execution logic. Supports both
|
|
175
|
+
static options and dynamic option suppliers.
|
|
135
176
|
|
|
136
177
|
```typescript jsx
|
|
137
|
-
import {
|
|
178
|
+
import { usePromiseState, PromiseStatus } from '@ahoo-wang/fetcher-react';
|
|
138
179
|
|
|
139
180
|
const MyComponent = () => {
|
|
140
|
-
const {
|
|
141
|
-
initialQuery: { condition: {}, projection: {}, sort: [], limit: 10 },
|
|
142
|
-
list: async (listQuery) => fetchListData(listQuery),
|
|
143
|
-
autoExecute: true, // Automatically execute on component mount
|
|
144
|
-
});
|
|
145
|
-
|
|
146
|
-
// The query will execute automatically when the component mounts
|
|
147
|
-
// You can still manually trigger it with execute() or update conditions
|
|
181
|
+
const { status, loading, result, error, setSuccess, setError, setIdle } = usePromiseState<string>();
|
|
148
182
|
|
|
149
|
-
|
|
150
|
-
|
|
183
|
+
const handleSuccess = () => setSuccess('Data loaded');
|
|
184
|
+
const handleError = () => setError(new Error('Failed to load'));
|
|
151
185
|
|
|
152
186
|
return (
|
|
153
187
|
<div>
|
|
154
|
-
<
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
188
|
+
<button onClick={handleSuccess}>Set Success</button>
|
|
189
|
+
<button onClick={handleError}>Set Error</button>
|
|
190
|
+
<button onClick={setIdle}>Reset</button>
|
|
191
|
+
<p>Status: {status}</p>
|
|
192
|
+
{loading && <p>Loading...</p>}
|
|
193
|
+
{result && <p>Result: {result}</p>}
|
|
194
|
+
{error && <p>Error: {error.message}</p>}
|
|
159
195
|
</div>
|
|
160
196
|
);
|
|
161
197
|
};
|
|
162
198
|
```
|
|
163
199
|
|
|
164
|
-
|
|
200
|
+
##### usePromiseState with Options Supplier
|
|
165
201
|
|
|
166
|
-
|
|
202
|
+
```typescript jsx
|
|
203
|
+
import { usePromiseState, PromiseStatus } from '@ahoo-wang/fetcher-react';
|
|
167
204
|
|
|
168
|
-
|
|
205
|
+
const MyComponent = () => {
|
|
206
|
+
// Using options supplier for dynamic configuration
|
|
207
|
+
const optionsSupplier = () => ({
|
|
208
|
+
initialStatus: PromiseStatus.IDLE,
|
|
209
|
+
onSuccess: async (result: string) => {
|
|
210
|
+
await saveToAnalytics(result);
|
|
211
|
+
console.log('Success:', result);
|
|
212
|
+
},
|
|
213
|
+
onError: async (error) => {
|
|
214
|
+
await logErrorToServer(error);
|
|
215
|
+
console.error('Error:', error);
|
|
216
|
+
},
|
|
217
|
+
});
|
|
169
218
|
|
|
170
|
-
|
|
219
|
+
const { setSuccess, setError } = usePromiseState<string>(optionsSupplier);
|
|
220
|
+
|
|
221
|
+
return (
|
|
222
|
+
<div>
|
|
223
|
+
<button onClick={() => setSuccess('Dynamic success!')}>Set Success</button>
|
|
224
|
+
<button onClick={() => setError(new Error('Dynamic error!'))}>Set Error</button>
|
|
225
|
+
</div>
|
|
226
|
+
);
|
|
227
|
+
};
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
#### useRequestId Hook
|
|
231
|
+
|
|
232
|
+
The `useRequestId` hook provides request ID management for preventing race conditions in async operations.
|
|
171
233
|
|
|
172
234
|
```typescript jsx
|
|
173
|
-
import {
|
|
235
|
+
import { useRequestId } from '@ahoo-wang/fetcher-react';
|
|
174
236
|
|
|
175
|
-
const
|
|
176
|
-
const {
|
|
177
|
-
async (query: string) => {
|
|
178
|
-
const response = await fetch(`/api/search?q=${query}`);
|
|
179
|
-
const results = await response.json();
|
|
180
|
-
console.log('Search results:', results);
|
|
181
|
-
},
|
|
182
|
-
{ delay: 300 }
|
|
183
|
-
);
|
|
237
|
+
const MyComponent = () => {
|
|
238
|
+
const { generate, isLatest, invalidate } = useRequestId();
|
|
184
239
|
|
|
185
|
-
const
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
240
|
+
const handleFetch = async () => {
|
|
241
|
+
const requestId = generate();
|
|
242
|
+
|
|
243
|
+
try {
|
|
244
|
+
const result = await fetchData();
|
|
245
|
+
|
|
246
|
+
if (isLatest(requestId)) {
|
|
247
|
+
setData(result);
|
|
248
|
+
}
|
|
249
|
+
} catch (error) {
|
|
250
|
+
if (isLatest(requestId)) {
|
|
251
|
+
setError(error);
|
|
252
|
+
}
|
|
190
253
|
}
|
|
191
254
|
};
|
|
192
255
|
|
|
193
256
|
return (
|
|
194
257
|
<div>
|
|
195
|
-
<
|
|
196
|
-
|
|
197
|
-
placeholder="Search..."
|
|
198
|
-
onChange={(e) => handleSearch(e.target.value)}
|
|
199
|
-
/>
|
|
200
|
-
{isPending() && <div>Searching...</div>}
|
|
258
|
+
<button onClick={handleFetch}>Fetch Data</button>
|
|
259
|
+
<button onClick={invalidate}>Cancel Ongoing</button>
|
|
201
260
|
</div>
|
|
202
261
|
);
|
|
203
262
|
};
|
|
204
263
|
```
|
|
205
264
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
- `delay`: Delay in milliseconds before execution (required, positive number)
|
|
209
|
-
- `leading`: Execute immediately on first call (default: false)
|
|
210
|
-
- `trailing`: Execute after delay on last call (default: true)
|
|
211
|
-
|
|
212
|
-
#### useDebouncedExecutePromise
|
|
265
|
+
#### useLatest Hook
|
|
213
266
|
|
|
214
|
-
|
|
267
|
+
The `useLatest` hook returns a ref containing the latest value, useful for accessing the current value in async
|
|
268
|
+
callbacks.
|
|
215
269
|
|
|
216
270
|
```typescript jsx
|
|
217
|
-
import {
|
|
271
|
+
import { useLatest } from '@ahoo-wang/fetcher-react';
|
|
218
272
|
|
|
219
|
-
const
|
|
220
|
-
const
|
|
221
|
-
|
|
222
|
-
});
|
|
273
|
+
const MyComponent = () => {
|
|
274
|
+
const [count, setCount] = useState(0);
|
|
275
|
+
const latestCount = useLatest(count);
|
|
223
276
|
|
|
224
|
-
const
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
return response.json();
|
|
228
|
-
});
|
|
277
|
+
const handleAsync = async () => {
|
|
278
|
+
await someAsyncOperation();
|
|
279
|
+
console.log('Latest count:', latestCount.current); // Always the latest
|
|
229
280
|
};
|
|
230
281
|
|
|
231
282
|
return (
|
|
232
283
|
<div>
|
|
233
|
-
<
|
|
234
|
-
|
|
235
|
-
</button>
|
|
236
|
-
{loading && <div>Loading...</div>}
|
|
237
|
-
{error && <div>Error: {error.message}</div>}
|
|
238
|
-
{result && <div>User: {result.name}</div>}
|
|
284
|
+
<p>Count: {count}</p>
|
|
285
|
+
<button onClick={() => setCount(c => c + 1)}>Increment</button>
|
|
286
|
+
<button onClick={handleAsync}>Async Log</button>
|
|
239
287
|
</div>
|
|
240
288
|
);
|
|
241
289
|
};
|
|
242
290
|
```
|
|
243
291
|
|
|
244
|
-
####
|
|
292
|
+
#### useRefs Hook
|
|
245
293
|
|
|
246
|
-
|
|
294
|
+
The `useRefs` hook provides a Map-like interface for managing multiple React refs dynamically. It allows registering, retrieving, and managing refs by key, with automatic cleanup on component unmount.
|
|
247
295
|
|
|
248
296
|
```typescript jsx
|
|
249
|
-
import {
|
|
297
|
+
import { useRefs } from '@ahoo-wang/fetcher-react';
|
|
250
298
|
|
|
251
|
-
const
|
|
252
|
-
const
|
|
253
|
-
const { loading, result, error, run } = useDebouncedFetcher({
|
|
254
|
-
debounce: { delay: 300 },
|
|
255
|
-
onSuccess: (data) => {
|
|
256
|
-
setSearchResults(data.results);
|
|
257
|
-
}
|
|
258
|
-
});
|
|
299
|
+
const MyComponent = () => {
|
|
300
|
+
const refs = useRefs<HTMLDivElement>();
|
|
259
301
|
|
|
260
|
-
const
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
run({
|
|
264
|
-
url: '/api/search',
|
|
265
|
-
method: 'GET',
|
|
266
|
-
params: { q: value }
|
|
267
|
-
});
|
|
268
|
-
}
|
|
302
|
+
const handleFocus = (key: string) => {
|
|
303
|
+
const element = refs.get(key);
|
|
304
|
+
element?.focus();
|
|
269
305
|
};
|
|
270
306
|
|
|
271
307
|
return (
|
|
272
308
|
<div>
|
|
273
|
-
<
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
/>
|
|
278
|
-
{loading && <div>Searching...</div>}
|
|
279
|
-
{error && <div>Error: {error.message}</div>}
|
|
280
|
-
{result && <SearchResults data={result} />}
|
|
309
|
+
<div ref={refs.register('first')} tabIndex={0}>First Element</div>
|
|
310
|
+
<div ref={refs.register('second')} tabIndex={0}>Second Element</div>
|
|
311
|
+
<button onClick={() => handleFocus('first')}>Focus First</button>
|
|
312
|
+
<button onClick={() => handleFocus('second')}>Focus Second</button>
|
|
281
313
|
</div>
|
|
282
314
|
);
|
|
283
315
|
};
|
|
284
316
|
```
|
|
285
317
|
|
|
286
|
-
|
|
318
|
+
Key features:
|
|
287
319
|
|
|
288
|
-
- **
|
|
289
|
-
- **
|
|
290
|
-
- **
|
|
320
|
+
- **Dynamic Registration**: Register refs with string, number, or symbol keys
|
|
321
|
+
- **Map-like API**: Full Map interface with get, set, has, delete, etc.
|
|
322
|
+
- **Automatic Cleanup**: Refs are cleared when component unmounts
|
|
323
|
+
- **Type Safety**: Full TypeScript support for ref types
|
|
291
324
|
|
|
292
|
-
####
|
|
325
|
+
#### useQuery Hook
|
|
293
326
|
|
|
294
|
-
|
|
327
|
+
The `useQuery` hook provides a complete solution for managing query-based asynchronous operations with automatic state management and execution control.
|
|
295
328
|
|
|
296
329
|
```typescript jsx
|
|
297
|
-
import {
|
|
330
|
+
import { useQuery } from '@ahoo-wang/fetcher-react';
|
|
298
331
|
|
|
299
|
-
interface
|
|
300
|
-
|
|
301
|
-
limit: number;
|
|
302
|
-
filters?: { category?: string };
|
|
332
|
+
interface UserQuery {
|
|
333
|
+
id: string;
|
|
303
334
|
}
|
|
304
335
|
|
|
305
|
-
interface
|
|
306
|
-
|
|
307
|
-
|
|
336
|
+
interface User {
|
|
337
|
+
id: string;
|
|
338
|
+
name: string;
|
|
308
339
|
}
|
|
309
340
|
|
|
310
|
-
|
|
311
|
-
const {
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
setQuery,
|
|
319
|
-
getQuery,
|
|
320
|
-
} = useDebouncedFetcherQuery<SearchQuery, SearchResult>({
|
|
321
|
-
url: '/api/search',
|
|
322
|
-
initialQuery: { keyword: '', limit: 10 },
|
|
323
|
-
debounce: { delay: 300 }, // Debounce for 300ms
|
|
324
|
-
autoExecute: false, // Don't execute on mount
|
|
341
|
+
function UserComponent() {
|
|
342
|
+
const { loading, result, error, execute, setQuery } = useQuery<UserQuery, User>({
|
|
343
|
+
initialQuery: { id: '1' },
|
|
344
|
+
execute: async (query) => {
|
|
345
|
+
const response = await fetch(`/api/users/${query.id}`);
|
|
346
|
+
return response.json();
|
|
347
|
+
},
|
|
348
|
+
autoExecute: true,
|
|
325
349
|
});
|
|
326
350
|
|
|
327
|
-
const
|
|
328
|
-
setQuery({
|
|
351
|
+
const handleUserChange = (userId: string) => {
|
|
352
|
+
setQuery({ id: userId }); // Automatically executes if autoExecute is true
|
|
329
353
|
};
|
|
330
354
|
|
|
331
|
-
|
|
332
|
-
|
|
355
|
+
if (loading) return <div>Loading...</div>;
|
|
356
|
+
if (error) return <div>Error: {error.message}</div>;
|
|
357
|
+
return (
|
|
358
|
+
<div>
|
|
359
|
+
<button onClick={() => handleUserChange('2')}>Load User 2</button>
|
|
360
|
+
{result && <p>User: {result.name}</p>}
|
|
361
|
+
</div>
|
|
362
|
+
);
|
|
363
|
+
}
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
#### useQueryState Hook
|
|
367
|
+
|
|
368
|
+
The `useQueryState` hook provides state management for query parameters with automatic execution capabilities.
|
|
369
|
+
|
|
370
|
+
```typescript jsx
|
|
371
|
+
import { useQueryState } from '@ahoo-wang/fetcher-react';
|
|
372
|
+
|
|
373
|
+
interface UserQuery {
|
|
374
|
+
id: string;
|
|
375
|
+
name?: string;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
function UserComponent() {
|
|
379
|
+
const executeQuery = async (query: UserQuery) => {
|
|
380
|
+
// Perform query execution logic here
|
|
381
|
+
console.log('Executing query:', query);
|
|
333
382
|
};
|
|
334
383
|
|
|
335
|
-
const
|
|
336
|
-
|
|
384
|
+
const { getQuery, setQuery } = useQueryState<UserQuery>({
|
|
385
|
+
initialQuery: { id: '1' },
|
|
386
|
+
autoExecute: true,
|
|
387
|
+
execute: executeQuery,
|
|
388
|
+
});
|
|
389
|
+
|
|
390
|
+
const handleQueryChange = (newQuery: UserQuery) => {
|
|
391
|
+
setQuery(newQuery); // Will automatically execute if autoExecute is true
|
|
337
392
|
};
|
|
338
393
|
|
|
339
|
-
|
|
340
|
-
|
|
394
|
+
const currentQuery = getQuery(); // Get current query parameters
|
|
395
|
+
|
|
396
|
+
return (
|
|
397
|
+
<div>
|
|
398
|
+
<button onClick={() => handleQueryChange({ id: '2', name: 'John' })}>
|
|
399
|
+
Update Query
|
|
400
|
+
</button>
|
|
401
|
+
</div>
|
|
402
|
+
);
|
|
403
|
+
}
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
#### useMounted Hook
|
|
407
|
+
|
|
408
|
+
The `useMounted` hook provides a way to check if a component is still mounted, useful for avoiding state updates on unmounted components.
|
|
409
|
+
|
|
410
|
+
```typescript jsx
|
|
411
|
+
import { useMounted } from '@ahoo-wang/fetcher-react';
|
|
412
|
+
|
|
413
|
+
const MyComponent = () => {
|
|
414
|
+
const isMounted = useMounted();
|
|
415
|
+
|
|
416
|
+
const handleAsyncOperation = async () => {
|
|
417
|
+
const result = await someAsyncOperation();
|
|
418
|
+
|
|
419
|
+
// Check if component is still mounted before updating state
|
|
420
|
+
if (isMounted()) {
|
|
421
|
+
setData(result);
|
|
422
|
+
}
|
|
423
|
+
};
|
|
424
|
+
|
|
425
|
+
return (
|
|
426
|
+
<div>
|
|
427
|
+
<button onClick={handleAsyncOperation}>Perform Async Operation</button>
|
|
428
|
+
</div>
|
|
429
|
+
);
|
|
430
|
+
};
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
#### useForceUpdate Hook
|
|
434
|
+
|
|
435
|
+
The `useForceUpdate` hook provides a way to force a component to re-render, useful when you need to trigger a render based on external changes.
|
|
436
|
+
|
|
437
|
+
```typescript jsx
|
|
438
|
+
import { useForceUpdate } from '@ahoo-wang/fetcher-react';
|
|
439
|
+
|
|
440
|
+
const MyComponent = () => {
|
|
441
|
+
const forceUpdate = useForceUpdate();
|
|
442
|
+
|
|
443
|
+
const handleExternalChange = () => {
|
|
444
|
+
// Perform some external operation that doesn't trigger a re-render
|
|
445
|
+
updateExternalState();
|
|
446
|
+
|
|
447
|
+
// Force the component to re-render to reflect the changes
|
|
448
|
+
forceUpdate();
|
|
449
|
+
};
|
|
450
|
+
|
|
451
|
+
return (
|
|
452
|
+
<div>
|
|
453
|
+
<button onClick={handleExternalChange}>Force Update</button>
|
|
454
|
+
</div>
|
|
455
|
+
);
|
|
456
|
+
};
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
### Debounced Hooks
|
|
460
|
+
|
|
461
|
+
🚀 **Advanced Debouncing for React Applications** - Powerful hooks that combine debouncing with async operations, providing seamless rate limiting for API calls, user interactions, and promise execution.
|
|
462
|
+
|
|
463
|
+
#### useDebouncedCallback
|
|
464
|
+
|
|
465
|
+
A React hook that provides a debounced version of any callback function with leading/trailing edge execution options.
|
|
466
|
+
|
|
467
|
+
```typescript jsx
|
|
468
|
+
import { useDebouncedCallback } from '@ahoo-wang/fetcher-react';
|
|
469
|
+
|
|
470
|
+
const SearchComponent = () => {
|
|
471
|
+
const { run: debouncedSearch, cancel, isPending } = useDebouncedCallback(
|
|
472
|
+
async (query: string) => {
|
|
473
|
+
const response = await fetch(`/api/search?q=${query}`);
|
|
474
|
+
const results = await response.json();
|
|
475
|
+
console.log('Search results:', results);
|
|
476
|
+
},
|
|
477
|
+
{ delay: 300 }
|
|
478
|
+
);
|
|
479
|
+
|
|
480
|
+
const handleSearch = (query: string) => {
|
|
481
|
+
if (query.trim()) {
|
|
482
|
+
debouncedSearch(query);
|
|
483
|
+
} else {
|
|
484
|
+
cancel(); // Cancel any pending search
|
|
485
|
+
}
|
|
486
|
+
};
|
|
341
487
|
|
|
342
488
|
return (
|
|
343
489
|
<div>
|
|
344
490
|
<input
|
|
345
491
|
type="text"
|
|
346
|
-
onChange={(e) => handleSearch(e.target.value)}
|
|
347
492
|
placeholder="Search..."
|
|
493
|
+
onChange={(e) => handleSearch(e.target.value)}
|
|
348
494
|
/>
|
|
349
|
-
|
|
350
|
-
{isPending() ? 'Searching...' : 'Search'}
|
|
351
|
-
</button>
|
|
352
|
-
<button onClick={handleCancel}>Cancel</button>
|
|
353
|
-
{result && (
|
|
354
|
-
<div>
|
|
355
|
-
Found {result.total} items:
|
|
356
|
-
{result.items.map(item => (
|
|
357
|
-
<div key={item.id}>{item.title}</div>
|
|
358
|
-
))}
|
|
359
|
-
</div>
|
|
360
|
-
)}
|
|
495
|
+
{isPending() && <div>Searching...</div>}
|
|
361
496
|
</div>
|
|
362
497
|
);
|
|
363
498
|
};
|
|
364
499
|
```
|
|
365
500
|
|
|
366
|
-
**
|
|
501
|
+
**Configuration Options:**
|
|
367
502
|
|
|
368
|
-
-
|
|
369
|
-
-
|
|
370
|
-
-
|
|
371
|
-
|
|
372
|
-
|
|
503
|
+
- `delay`: Delay in milliseconds before execution (required, positive number)
|
|
504
|
+
- `leading`: Execute immediately on first call (default: false)
|
|
505
|
+
- `trailing`: Execute after delay on last call (default: true)
|
|
506
|
+
|
|
507
|
+
#### useDebouncedExecutePromise
|
|
508
|
+
|
|
509
|
+
Combines promise execution with debouncing functionality, perfect for API calls and async operations.
|
|
510
|
+
|
|
511
|
+
```typescript jsx
|
|
512
|
+
import { useDebouncedExecutePromise } from '@ahoo-wang/fetcher-react';
|
|
513
|
+
|
|
514
|
+
const DataFetcher = () => {
|
|
515
|
+
const { loading, result, error, run } = useDebouncedExecutePromise({
|
|
516
|
+
debounce: { delay: 300 },
|
|
517
|
+
});
|
|
518
|
+
|
|
519
|
+
const handleLoadUser = (userId: string) => {
|
|
520
|
+
run(async () => {
|
|
521
|
+
const response = await fetch(`/api/users/${userId}`);
|
|
522
|
+
return response.json();
|
|
523
|
+
});
|
|
524
|
+
};
|
|
525
|
+
|
|
526
|
+
return (
|
|
527
|
+
<div>
|
|
528
|
+
<button onClick={() => handleLoadUser('user123')}>
|
|
529
|
+
Load User
|
|
530
|
+
</button>
|
|
531
|
+
{loading && <div>Loading...</div>}
|
|
532
|
+
{error && <div>Error: {error.message}</div>}
|
|
533
|
+
{result && <div>User: {result.name}</div>}
|
|
534
|
+
</div>
|
|
535
|
+
);
|
|
536
|
+
};
|
|
537
|
+
```
|
|
373
538
|
|
|
374
539
|
#### useDebouncedQuery
|
|
375
540
|
|
|
@@ -461,382 +626,222 @@ const SearchComponent = () => {
|
|
|
461
626
|
- **Pending State**: `isPending()` to check if a debounced call is queued
|
|
462
627
|
- **Custom Execution**: Flexible execute function for any query operation
|
|
463
628
|
|
|
464
|
-
###
|
|
629
|
+
### Fetcher Hooks
|
|
465
630
|
|
|
466
|
-
|
|
467
|
-
|
|
631
|
+
#### useFetcher Hook
|
|
632
|
+
|
|
633
|
+
The `useFetcher` hook provides complete data fetching capabilities with automatic state management, race condition
|
|
634
|
+
protection, and flexible configuration options. It includes built-in AbortController support inherited from `useExecutePromise`.
|
|
468
635
|
|
|
469
636
|
```typescript jsx
|
|
470
|
-
import {
|
|
637
|
+
import { useFetcher } from '@ahoo-wang/fetcher-react';
|
|
471
638
|
|
|
472
639
|
const MyComponent = () => {
|
|
473
|
-
const { loading,
|
|
640
|
+
const { loading, error, result, execute, abort } = useFetcher<string>({
|
|
474
641
|
onAbort: () => {
|
|
475
|
-
console.log('
|
|
642
|
+
console.log('Fetch operation was aborted');
|
|
476
643
|
}
|
|
477
644
|
});
|
|
478
645
|
|
|
479
|
-
const fetchData = async () => {
|
|
480
|
-
const response = await fetch('/api/data');
|
|
481
|
-
return response.text();
|
|
482
|
-
};
|
|
483
|
-
|
|
484
646
|
const handleFetch = () => {
|
|
485
|
-
execute(
|
|
486
|
-
};
|
|
487
|
-
|
|
488
|
-
const handleDirectPromise = () => {
|
|
489
|
-
const promise = fetch('/api/data').then(res => res.text());
|
|
490
|
-
execute(promise); // Using a direct promise
|
|
647
|
+
execute({ url: '/api/users', method: 'GET' });
|
|
491
648
|
};
|
|
492
649
|
|
|
493
650
|
const handleAbort = () => {
|
|
494
|
-
abort(); //
|
|
651
|
+
abort(); // Cancel the current fetch operation
|
|
495
652
|
};
|
|
496
|
-
|
|
497
|
-
if (loading) return <div>Loading...</div>;
|
|
498
|
-
if (error) return <div>Error: {error.message}</div>;
|
|
499
|
-
return (
|
|
500
|
-
<div>
|
|
501
|
-
<button onClick={handleFetch}>Fetch with Supplier</button>
|
|
502
|
-
<button onClick={handleDirectPromise}>Fetch with Promise</button>
|
|
503
|
-
<button onClick={handleAbort} disabled={!loading}>Abort</button>
|
|
504
|
-
<button onClick={reset}>Reset</button>
|
|
505
|
-
{result && <p>{result}</p>}
|
|
506
|
-
</div>
|
|
507
|
-
);
|
|
508
|
-
};
|
|
509
653
|
```
|
|
510
654
|
|
|
511
|
-
####
|
|
512
|
-
|
|
513
|
-
The hook automatically creates an AbortController for each operation and provides methods to manage cancellation:
|
|
514
|
-
|
|
515
|
-
- **Automatic Cleanup**: Operations are automatically aborted when the component unmounts
|
|
516
|
-
- **Manual Abort**: Use the `abort()` method to cancel ongoing operations
|
|
517
|
-
- **onAbort Callback**: Configure a callback that fires when an operation is aborted (manually or automatically)
|
|
518
|
-
- **AbortController Access**: The AbortController is passed to promise suppliers for advanced cancellation handling
|
|
519
|
-
|
|
520
|
-
### usePromiseState Hook
|
|
521
|
-
|
|
522
|
-
The `usePromiseState` hook provides state management for promise operations without execution logic. Supports both
|
|
523
|
-
static options and dynamic option suppliers.
|
|
524
|
-
|
|
525
|
-
```typescript jsx
|
|
526
|
-
import { usePromiseState, PromiseStatus } from '@ahoo-wang/fetcher-react';
|
|
527
|
-
|
|
528
|
-
const MyComponent = () => {
|
|
529
|
-
const { status, loading, result, error, setSuccess, setError, setIdle } = usePromiseState<string>();
|
|
530
|
-
|
|
531
|
-
const handleSuccess = () => setSuccess('Data loaded');
|
|
532
|
-
const handleError = () => setError(new Error('Failed to load'));
|
|
533
|
-
|
|
534
|
-
return (
|
|
535
|
-
<div>
|
|
536
|
-
<button onClick={handleSuccess}>Set Success</button>
|
|
537
|
-
<button onClick={handleError}>Set Error</button>
|
|
538
|
-
<button onClick={setIdle}>Reset</button>
|
|
539
|
-
<p>Status: {status}</p>
|
|
540
|
-
{loading && <p>Loading...</p>}
|
|
541
|
-
{result && <p>Result: {result}</p>}
|
|
542
|
-
{error && <p>Error: {error.message}</p>}
|
|
543
|
-
</div>
|
|
544
|
-
);
|
|
545
|
-
};
|
|
546
|
-
```
|
|
547
|
-
|
|
548
|
-
#### usePromiseState with Options Supplier
|
|
655
|
+
#### Auto Execute Example
|
|
549
656
|
|
|
550
657
|
```typescript jsx
|
|
551
|
-
import {
|
|
658
|
+
import { useListQuery } from '@ahoo-wang/fetcher-react';
|
|
552
659
|
|
|
553
660
|
const MyComponent = () => {
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
await saveToAnalytics(result);
|
|
559
|
-
console.log('Success:', result);
|
|
560
|
-
},
|
|
561
|
-
onError: async (error) => {
|
|
562
|
-
await logErrorToServer(error);
|
|
563
|
-
console.error('Error:', error);
|
|
564
|
-
},
|
|
661
|
+
const { result, loading, error, execute, setCondition } = useListQuery({
|
|
662
|
+
initialQuery: { condition: {}, projection: {}, sort: [], limit: 10 },
|
|
663
|
+
list: async (listQuery) => fetchListData(listQuery),
|
|
664
|
+
autoExecute: true, // Automatically execute on component mount
|
|
565
665
|
});
|
|
566
666
|
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
return (
|
|
570
|
-
<div>
|
|
571
|
-
<button onClick={() => setSuccess('Dynamic success!')}>Set Success</button>
|
|
572
|
-
<button onClick={() => setError(new Error('Dynamic error!'))}>Set Error</button>
|
|
573
|
-
</div>
|
|
574
|
-
);
|
|
575
|
-
};
|
|
576
|
-
```
|
|
577
|
-
|
|
578
|
-
### Utility Hooks
|
|
579
|
-
|
|
580
|
-
#### useRequestId Hook
|
|
581
|
-
|
|
582
|
-
The `useRequestId` hook provides request ID management for preventing race conditions in async operations.
|
|
583
|
-
|
|
584
|
-
```typescript jsx
|
|
585
|
-
import { useRequestId } from '@ahoo-wang/fetcher-react';
|
|
586
|
-
|
|
587
|
-
const MyComponent = () => {
|
|
588
|
-
const { generate, isLatest, invalidate } = useRequestId();
|
|
589
|
-
|
|
590
|
-
const handleFetch = async () => {
|
|
591
|
-
const requestId = generate();
|
|
592
|
-
|
|
593
|
-
try {
|
|
594
|
-
const result = await fetchData();
|
|
595
|
-
|
|
596
|
-
if (isLatest(requestId)) {
|
|
597
|
-
setData(result);
|
|
598
|
-
}
|
|
599
|
-
} catch (error) {
|
|
600
|
-
if (isLatest(requestId)) {
|
|
601
|
-
setError(error);
|
|
602
|
-
}
|
|
603
|
-
}
|
|
604
|
-
};
|
|
605
|
-
|
|
606
|
-
return (
|
|
607
|
-
<div>
|
|
608
|
-
<button onClick={handleFetch}>Fetch Data</button>
|
|
609
|
-
<button onClick={invalidate}>Cancel Ongoing</button>
|
|
610
|
-
</div>
|
|
611
|
-
);
|
|
612
|
-
};
|
|
613
|
-
```
|
|
614
|
-
|
|
615
|
-
### useLatest Hook
|
|
616
|
-
|
|
617
|
-
The `useLatest` hook returns a ref containing the latest value, useful for accessing the current value in async
|
|
618
|
-
callbacks.
|
|
619
|
-
|
|
620
|
-
```typescript jsx
|
|
621
|
-
import { useLatest } from '@ahoo-wang/fetcher-react';
|
|
622
|
-
|
|
623
|
-
const MyComponent = () => {
|
|
624
|
-
const [count, setCount] = useState(0);
|
|
625
|
-
const latestCount = useLatest(count);
|
|
667
|
+
// The query will execute automatically when the component mounts
|
|
668
|
+
// You can still manually trigger it with execute() or update conditions
|
|
626
669
|
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
console.log('Latest count:', latestCount.current); // Always the latest
|
|
630
|
-
};
|
|
670
|
+
if (loading) return <div>Loading...</div>;
|
|
671
|
+
if (error) return <div>Error: {error.message}</div>;
|
|
631
672
|
|
|
632
673
|
return (
|
|
633
674
|
<div>
|
|
634
|
-
<
|
|
635
|
-
|
|
636
|
-
|
|
675
|
+
<ul>
|
|
676
|
+
{result?.map((item, index) => (
|
|
677
|
+
<li key={index}>{item.name}</li>
|
|
678
|
+
))}
|
|
679
|
+
</ul>
|
|
637
680
|
</div>
|
|
638
681
|
);
|
|
639
682
|
};
|
|
640
683
|
```
|
|
641
684
|
|
|
642
|
-
|
|
685
|
+
#### useFetcherQuery Hook
|
|
643
686
|
|
|
644
|
-
The `
|
|
687
|
+
The `useFetcherQuery` hook provides a foundation for building specialized query hooks that integrate with the Fetcher library.
|
|
645
688
|
|
|
646
689
|
```typescript jsx
|
|
647
|
-
import {
|
|
690
|
+
import { useFetcherQuery } from '@ahoo-wang/fetcher-react';
|
|
648
691
|
|
|
649
692
|
const MyComponent = () => {
|
|
650
|
-
const
|
|
693
|
+
const { data, loading, error, execute } = useFetcherQuery({
|
|
694
|
+
url: '/api/data',
|
|
695
|
+
initialQuery: { /* query parameters */ },
|
|
696
|
+
execute: async (query) => {
|
|
697
|
+
// Custom execution logic
|
|
698
|
+
return fetchData(query);
|
|
699
|
+
},
|
|
700
|
+
autoExecute: true,
|
|
701
|
+
});
|
|
651
702
|
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
element?.focus();
|
|
655
|
-
};
|
|
703
|
+
if (loading) return <div>Loading...</div>;
|
|
704
|
+
if (error) return <div>Error: {error.message}</div>;
|
|
656
705
|
|
|
657
706
|
return (
|
|
658
707
|
<div>
|
|
659
|
-
<
|
|
660
|
-
<div ref={refs.register('second')} tabIndex={0}>Second Element</div>
|
|
661
|
-
<button onClick={() => handleFocus('first')}>Focus First</button>
|
|
662
|
-
<button onClick={() => handleFocus('second')}>Focus Second</button>
|
|
708
|
+
<pre>{JSON.stringify(data, null, 2)}</pre>
|
|
663
709
|
</div>
|
|
664
710
|
);
|
|
665
711
|
};
|
|
666
712
|
```
|
|
667
713
|
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
- **Dynamic Registration**: Register refs with string, number, or symbol keys
|
|
671
|
-
- **Map-like API**: Full Map interface with get, set, has, delete, etc.
|
|
672
|
-
- **Automatic Cleanup**: Refs are cleared when component unmounts
|
|
673
|
-
- **Type Safety**: Full TypeScript support for ref types
|
|
714
|
+
### Debounced Fetcher Hooks
|
|
674
715
|
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
#### useEventSubscription Hook
|
|
678
|
-
|
|
679
|
-
The `useEventSubscription` hook provides a React interface for subscribing to typed event buses. It automatically manages subscription lifecycle while offering manual control functions for additional flexibility.
|
|
680
|
-
|
|
681
|
-
```typescript jsx
|
|
682
|
-
import { useEventSubscription } from '@ahoo-wang/fetcher-react';
|
|
683
|
-
import { eventBus } from './eventBus';
|
|
684
|
-
|
|
685
|
-
function MyComponent() {
|
|
686
|
-
const { subscribe, unsubscribe } = useEventSubscription({
|
|
687
|
-
bus: eventBus,
|
|
688
|
-
handler: {
|
|
689
|
-
name: 'myEvent',
|
|
690
|
-
handle: (event) => {
|
|
691
|
-
console.log('Received event:', event);
|
|
692
|
-
}
|
|
693
|
-
}
|
|
694
|
-
});
|
|
695
|
-
|
|
696
|
-
// The hook automatically subscribes on mount and unsubscribes on unmount
|
|
697
|
-
// You can also manually control subscription if needed
|
|
698
|
-
const handleToggleSubscription = () => {
|
|
699
|
-
if (someCondition) {
|
|
700
|
-
subscribe();
|
|
701
|
-
} else {
|
|
702
|
-
unsubscribe();
|
|
703
|
-
}
|
|
704
|
-
};
|
|
705
|
-
|
|
706
|
-
return <div>My Component</div>;
|
|
707
|
-
}
|
|
708
|
-
```
|
|
709
|
-
|
|
710
|
-
Key features:
|
|
711
|
-
|
|
712
|
-
- **Automatic Lifecycle Management**: Automatically subscribes on component mount and unsubscribes on unmount
|
|
713
|
-
- **Manual Control**: Provides `subscribe` and `unsubscribe` functions for additional control
|
|
714
|
-
- **Type Safety**: Full TypeScript support with generic event types
|
|
715
|
-
- **Error Handling**: Logs warnings for failed subscription attempts
|
|
716
|
-
- **Event Bus Integration**: Works seamlessly with `@ahoo-wang/fetcher-eventbus` TypedEventBus instances
|
|
717
|
-
|
|
718
|
-
### CoSec Security Hooks
|
|
719
|
-
|
|
720
|
-
🛡️ **Enterprise Security Integration** - Powerful React hooks for managing authentication state with CoSec tokens, providing seamless integration with enterprise security systems and automatic token lifecycle management.
|
|
721
|
-
|
|
722
|
-
#### useSecurity Hook
|
|
716
|
+
#### useDebouncedFetcher
|
|
723
717
|
|
|
724
|
-
|
|
718
|
+
Specialized hook combining HTTP fetching with debouncing, built on top of the core fetcher library.
|
|
725
719
|
|
|
726
720
|
```typescript jsx
|
|
727
|
-
import {
|
|
728
|
-
import { tokenStorage } from './tokenStorage';
|
|
729
|
-
import { useNavigate } from 'react-router-dom';
|
|
730
|
-
|
|
731
|
-
function App() {
|
|
732
|
-
const navigate = useNavigate();
|
|
721
|
+
import { useDebouncedFetcher } from '@ahoo-wang/fetcher-react';
|
|
733
722
|
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
// Redirect to login page after logout
|
|
741
|
-
navigate('/login');
|
|
723
|
+
const SearchInput = () => {
|
|
724
|
+
const [query, setQuery] = useState('');
|
|
725
|
+
const { loading, result, error, run } = useDebouncedFetcher({
|
|
726
|
+
debounce: { delay: 300 },
|
|
727
|
+
onSuccess: (data) => {
|
|
728
|
+
setSearchResults(data.results);
|
|
742
729
|
}
|
|
743
730
|
});
|
|
744
731
|
|
|
745
|
-
const
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
method: 'POST',
|
|
753
|
-
body: JSON.stringify({ username, password })
|
|
732
|
+
const handleChange = (value: string) => {
|
|
733
|
+
setQuery(value);
|
|
734
|
+
if (value.trim()) {
|
|
735
|
+
run({
|
|
736
|
+
url: '/api/search',
|
|
737
|
+
method: 'GET',
|
|
738
|
+
params: { q: value }
|
|
754
739
|
});
|
|
755
|
-
|
|
756
|
-
});
|
|
740
|
+
}
|
|
757
741
|
};
|
|
758
742
|
|
|
759
|
-
if (!authenticated) {
|
|
760
|
-
return <button onClick={handleSignIn}>Sign In</button>;
|
|
761
|
-
}
|
|
762
|
-
|
|
763
743
|
return (
|
|
764
744
|
<div>
|
|
765
|
-
<
|
|
766
|
-
|
|
745
|
+
<input
|
|
746
|
+
value={query}
|
|
747
|
+
onChange={(e) => handleChange(e.target.value)}
|
|
748
|
+
placeholder="Search..."
|
|
749
|
+
/>
|
|
750
|
+
{loading && <div>Searching...</div>}
|
|
751
|
+
{error && <div>Error: {error.message}</div>}
|
|
752
|
+
{result && <SearchResults data={result} />}
|
|
767
753
|
</div>
|
|
768
754
|
);
|
|
769
|
-
}
|
|
770
|
-
```
|
|
771
|
-
|
|
772
|
-
**Key Features:**
|
|
773
|
-
|
|
774
|
-
- **Reactive Authentication State**: Automatically updates when tokens change
|
|
775
|
-
- **Flexible Sign-in Methods**: Supports both direct tokens and async token providers
|
|
776
|
-
- **Lifecycle Callbacks**: Configurable callbacks for sign-in and sign-out events
|
|
777
|
-
- **Type Safety**: Full TypeScript support with CoSec JWT payload types
|
|
778
|
-
- **Token Persistence**: Integrates with TokenStorage for cross-session persistence
|
|
779
|
-
|
|
780
|
-
#### SecurityProvider
|
|
781
|
-
|
|
782
|
-
The `SecurityProvider` component wraps your application to provide authentication context through React context. It internally uses the `useSecurity` hook and makes authentication state available to all child components via the `useSecurityContext` hook.
|
|
783
|
-
|
|
784
|
-
```tsx
|
|
785
|
-
import { SecurityProvider } from '@ahoo-wang/fetcher-react';
|
|
786
|
-
import { tokenStorage } from './tokenStorage';
|
|
787
|
-
import { useNavigate } from 'react-router-dom';
|
|
788
|
-
|
|
789
|
-
function App() {
|
|
790
|
-
const navigate = useNavigate();
|
|
791
|
-
|
|
792
|
-
return (
|
|
793
|
-
<SecurityProvider
|
|
794
|
-
tokenStorage={tokenStorage}
|
|
795
|
-
onSignIn={() => navigate('/dashboard')}
|
|
796
|
-
onSignOut={() => navigate('/login')}
|
|
797
|
-
>
|
|
798
|
-
<MyApp />
|
|
799
|
-
</SecurityProvider>
|
|
800
|
-
);
|
|
801
|
-
}
|
|
755
|
+
};
|
|
802
756
|
```
|
|
803
757
|
|
|
804
|
-
**
|
|
758
|
+
**Debouncing Strategies:**
|
|
805
759
|
|
|
806
|
-
-
|
|
807
|
-
-
|
|
808
|
-
-
|
|
809
|
-
- `children`: Child components that will have access to security context
|
|
760
|
+
- **Leading Edge**: Execute immediately on first call, then debounce subsequent calls
|
|
761
|
+
- **Trailing Edge**: Execute after delay on last call (default behavior)
|
|
762
|
+
- **Leading + Trailing**: Execute immediately, then again after delay if called again
|
|
810
763
|
|
|
811
|
-
####
|
|
764
|
+
#### useDebouncedFetcherQuery
|
|
812
765
|
|
|
813
|
-
|
|
766
|
+
Combines query-based HTTP fetching with debouncing, perfect for search inputs and dynamic query scenarios where you want to debounce API calls based on query parameters.
|
|
814
767
|
|
|
815
|
-
```
|
|
816
|
-
import {
|
|
768
|
+
```typescript jsx
|
|
769
|
+
import { useDebouncedFetcherQuery } from '@ahoo-wang/fetcher-react';
|
|
817
770
|
|
|
818
|
-
|
|
819
|
-
|
|
771
|
+
interface SearchQuery {
|
|
772
|
+
keyword: string;
|
|
773
|
+
limit: number;
|
|
774
|
+
filters?: { category?: string };
|
|
775
|
+
}
|
|
820
776
|
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
777
|
+
interface SearchResult {
|
|
778
|
+
items: Array<{ id: string; title: string }>;
|
|
779
|
+
total: number;
|
|
780
|
+
}
|
|
781
|
+
|
|
782
|
+
const SearchComponent = () => {
|
|
783
|
+
const {
|
|
784
|
+
loading,
|
|
785
|
+
result,
|
|
786
|
+
error,
|
|
787
|
+
run,
|
|
788
|
+
cancel,
|
|
789
|
+
isPending,
|
|
790
|
+
setQuery,
|
|
791
|
+
getQuery,
|
|
792
|
+
} = useDebouncedFetcherQuery<SearchQuery, SearchResult>({
|
|
793
|
+
url: '/api/search',
|
|
794
|
+
initialQuery: { keyword: '', limit: 10 },
|
|
795
|
+
debounce: { delay: 300 }, // Debounce for 300ms
|
|
796
|
+
autoExecute: false, // Don't execute on mount
|
|
797
|
+
});
|
|
798
|
+
|
|
799
|
+
const handleSearch = (keyword: string) => {
|
|
800
|
+
setQuery({ keyword, limit: 10 }); // This will trigger debounced execution if autoExecute was true
|
|
801
|
+
};
|
|
802
|
+
|
|
803
|
+
const handleManualSearch = () => {
|
|
804
|
+
run(); // Manual debounced execution with current query
|
|
805
|
+
};
|
|
806
|
+
|
|
807
|
+
const handleCancel = () => {
|
|
808
|
+
cancel(); // Cancel any pending debounced execution
|
|
809
|
+
};
|
|
810
|
+
|
|
811
|
+
if (loading) return <div>Searching...</div>;
|
|
812
|
+
if (error) return <div>Error: {error.message}</div>;
|
|
824
813
|
|
|
825
814
|
return (
|
|
826
815
|
<div>
|
|
827
|
-
<
|
|
828
|
-
|
|
816
|
+
<input
|
|
817
|
+
type="text"
|
|
818
|
+
onChange={(e) => handleSearch(e.target.value)}
|
|
819
|
+
placeholder="Search..."
|
|
820
|
+
/>
|
|
821
|
+
<button onClick={handleManualSearch} disabled={isPending()}>
|
|
822
|
+
{isPending() ? 'Searching...' : 'Search'}
|
|
823
|
+
</button>
|
|
824
|
+
<button onClick={handleCancel}>Cancel</button>
|
|
825
|
+
{result && (
|
|
826
|
+
<div>
|
|
827
|
+
Found {result.total} items:
|
|
828
|
+
{result.items.map(item => (
|
|
829
|
+
<div key={item.id}>{item.title}</div>
|
|
830
|
+
))}
|
|
831
|
+
</div>
|
|
832
|
+
)}
|
|
829
833
|
</div>
|
|
830
834
|
);
|
|
831
|
-
}
|
|
835
|
+
};
|
|
832
836
|
```
|
|
833
837
|
|
|
834
|
-
**
|
|
838
|
+
**Key Features:**
|
|
835
839
|
|
|
836
|
-
- **
|
|
837
|
-
- **
|
|
838
|
-
- **
|
|
839
|
-
- **
|
|
840
|
+
- **Query State Management**: Automatic query parameter handling with `setQuery` and `getQuery`
|
|
841
|
+
- **Debounced Execution**: Prevents excessive API calls during rapid user input
|
|
842
|
+
- **Auto-Execution**: Optional automatic execution when query parameters change
|
|
843
|
+
- **Manual Control**: `run()` for manual execution, `cancel()` for cancellation
|
|
844
|
+
- **Pending State**: `isPending()` to check if a debounced call is queued
|
|
840
845
|
|
|
841
846
|
### Storage Hooks
|
|
842
847
|
|
|
@@ -1167,22 +1172,188 @@ const prefsStorage = new KeyStorage<UserPreferences>({
|
|
|
1167
1172
|
key: 'user-prefs',
|
|
1168
1173
|
});
|
|
1169
1174
|
|
|
1170
|
-
// TypeScript will catch invalid updates
|
|
1171
|
-
const [prefs, updatePrefs] = useImmerKeyStorage(prefsStorage);
|
|
1175
|
+
// TypeScript will catch invalid updates
|
|
1176
|
+
const [prefs, updatePrefs] = useImmerKeyStorage(prefsStorage);
|
|
1177
|
+
|
|
1178
|
+
// This will cause a TypeScript error:
|
|
1179
|
+
// updatePrefs(draft => { draft.theme = 'invalid'; });
|
|
1180
|
+
```
|
|
1181
|
+
|
|
1182
|
+
### Event Hooks
|
|
1183
|
+
|
|
1184
|
+
#### useEventSubscription Hook
|
|
1185
|
+
|
|
1186
|
+
The `useEventSubscription` hook provides a React interface for subscribing to typed event buses. It automatically manages subscription lifecycle while offering manual control functions for additional flexibility.
|
|
1187
|
+
|
|
1188
|
+
```typescript jsx
|
|
1189
|
+
import { useEventSubscription } from '@ahoo-wang/fetcher-react';
|
|
1190
|
+
import { eventBus } from './eventBus';
|
|
1191
|
+
|
|
1192
|
+
function MyComponent() {
|
|
1193
|
+
const { subscribe, unsubscribe } = useEventSubscription({
|
|
1194
|
+
bus: eventBus,
|
|
1195
|
+
handler: {
|
|
1196
|
+
name: 'myEvent',
|
|
1197
|
+
handle: (event) => {
|
|
1198
|
+
console.log('Received event:', event);
|
|
1199
|
+
}
|
|
1200
|
+
}
|
|
1201
|
+
});
|
|
1202
|
+
|
|
1203
|
+
// The hook automatically subscribes on mount and unsubscribes on unmount
|
|
1204
|
+
// You can also manually control subscription if needed
|
|
1205
|
+
const handleToggleSubscription = () => {
|
|
1206
|
+
if (someCondition) {
|
|
1207
|
+
subscribe();
|
|
1208
|
+
} else {
|
|
1209
|
+
unsubscribe();
|
|
1210
|
+
}
|
|
1211
|
+
};
|
|
1212
|
+
|
|
1213
|
+
return <div>My Component</div>;
|
|
1214
|
+
}
|
|
1215
|
+
```
|
|
1216
|
+
|
|
1217
|
+
Key features:
|
|
1218
|
+
|
|
1219
|
+
- **Automatic Lifecycle Management**: Automatically subscribes on component mount and unsubscribes on unmount
|
|
1220
|
+
- **Manual Control**: Provides `subscribe` and `unsubscribe` functions for additional control
|
|
1221
|
+
- **Type Safety**: Full TypeScript support with generic event types
|
|
1222
|
+
- **Error Handling**: Logs warnings for failed subscription attempts
|
|
1223
|
+
- **Event Bus Integration**: Works seamlessly with `@ahoo-wang/fetcher-eventbus` TypedEventBus instances
|
|
1224
|
+
|
|
1225
|
+
### CoSec Security Hooks
|
|
1226
|
+
|
|
1227
|
+
🛡️ **Enterprise Security Integration** - Powerful React hooks for managing authentication state with CoSec tokens, providing seamless integration with enterprise security systems and automatic token lifecycle management.
|
|
1228
|
+
|
|
1229
|
+
#### useSecurity Hook
|
|
1230
|
+
|
|
1231
|
+
The `useSecurity` hook provides reactive access to authentication state and operations using CoSec tokens. It integrates with TokenStorage to persist tokens and updates state reactively when tokens change.
|
|
1232
|
+
|
|
1233
|
+
```typescript jsx
|
|
1234
|
+
import { useSecurity } from '@ahoo-wang/fetcher-react';
|
|
1235
|
+
import { tokenStorage } from './tokenStorage';
|
|
1236
|
+
import { useNavigate } from 'react-router-dom';
|
|
1237
|
+
|
|
1238
|
+
function App() {
|
|
1239
|
+
const navigate = useNavigate();
|
|
1240
|
+
|
|
1241
|
+
const { currentUser, authenticated, signIn, signOut } = useSecurity(tokenStorage, {
|
|
1242
|
+
onSignIn: () => {
|
|
1243
|
+
// Redirect to dashboard after successful login
|
|
1244
|
+
navigate('/dashboard');
|
|
1245
|
+
},
|
|
1246
|
+
onSignOut: () => {
|
|
1247
|
+
// Redirect to login page after logout
|
|
1248
|
+
navigate('/login');
|
|
1249
|
+
}
|
|
1250
|
+
});
|
|
1251
|
+
|
|
1252
|
+
const handleSignIn = async () => {
|
|
1253
|
+
// Direct token
|
|
1254
|
+
await signIn(compositeToken);
|
|
1255
|
+
|
|
1256
|
+
// Or async function
|
|
1257
|
+
await signIn(async () => {
|
|
1258
|
+
const response = await fetch('/api/auth/login', {
|
|
1259
|
+
method: 'POST',
|
|
1260
|
+
body: JSON.stringify({ username, password })
|
|
1261
|
+
});
|
|
1262
|
+
return response.json();
|
|
1263
|
+
});
|
|
1264
|
+
};
|
|
1265
|
+
|
|
1266
|
+
if (!authenticated) {
|
|
1267
|
+
return <button onClick={handleSignIn}>Sign In</button>;
|
|
1268
|
+
}
|
|
1269
|
+
|
|
1270
|
+
return (
|
|
1271
|
+
<div>
|
|
1272
|
+
<p>Welcome, {currentUser.sub}!</p>
|
|
1273
|
+
<button onClick={signOut}>Sign Out</button>
|
|
1274
|
+
</div>
|
|
1275
|
+
);
|
|
1276
|
+
}
|
|
1277
|
+
```
|
|
1278
|
+
|
|
1279
|
+
**Key Features:**
|
|
1280
|
+
|
|
1281
|
+
- **Reactive Authentication State**: Automatically updates when tokens change
|
|
1282
|
+
- **Flexible Sign-in Methods**: Supports both direct tokens and async token providers
|
|
1283
|
+
- **Lifecycle Callbacks**: Configurable callbacks for sign-in and sign-out events
|
|
1284
|
+
- **Type Safety**: Full TypeScript support with CoSec JWT payload types
|
|
1285
|
+
- **Token Persistence**: Integrates with TokenStorage for cross-session persistence
|
|
1286
|
+
|
|
1287
|
+
#### SecurityProvider
|
|
1288
|
+
|
|
1289
|
+
The `SecurityProvider` component wraps your application to provide authentication context through React context. It internally uses the `useSecurity` hook and makes authentication state available to all child components via the `useSecurityContext` hook.
|
|
1290
|
+
|
|
1291
|
+
```tsx
|
|
1292
|
+
import { SecurityProvider } from '@ahoo-wang/fetcher-react';
|
|
1293
|
+
import { tokenStorage } from './tokenStorage';
|
|
1294
|
+
import { useNavigate } from 'react-router-dom';
|
|
1295
|
+
|
|
1296
|
+
function App() {
|
|
1297
|
+
const navigate = useNavigate();
|
|
1298
|
+
|
|
1299
|
+
return (
|
|
1300
|
+
<SecurityProvider
|
|
1301
|
+
tokenStorage={tokenStorage}
|
|
1302
|
+
onSignIn={() => navigate('/dashboard')}
|
|
1303
|
+
onSignOut={() => navigate('/login')}
|
|
1304
|
+
>
|
|
1305
|
+
<MyApp />
|
|
1306
|
+
</SecurityProvider>
|
|
1307
|
+
);
|
|
1308
|
+
}
|
|
1309
|
+
```
|
|
1310
|
+
|
|
1311
|
+
**Configuration Options:**
|
|
1312
|
+
|
|
1313
|
+
- `tokenStorage`: TokenStorage instance for managing authentication tokens
|
|
1314
|
+
- `onSignIn`: Callback function invoked when sign in is successful
|
|
1315
|
+
- `onSignOut`: Callback function invoked when sign out occurs
|
|
1316
|
+
- `children`: Child components that will have access to security context
|
|
1317
|
+
|
|
1318
|
+
#### useSecurityContext Hook
|
|
1319
|
+
|
|
1320
|
+
The `useSecurityContext` hook provides access to authentication state and methods within components wrapped by `SecurityProvider`. It offers the same interface as `useSecurity` but through React context.
|
|
1321
|
+
|
|
1322
|
+
```tsx
|
|
1323
|
+
import { useSecurityContext } from '@ahoo-wang/fetcher-react';
|
|
1324
|
+
|
|
1325
|
+
function UserProfile() {
|
|
1326
|
+
const { currentUser, authenticated, signOut } = useSecurityContext();
|
|
1327
|
+
|
|
1328
|
+
if (!authenticated) {
|
|
1329
|
+
return <div>Please sign in</div>;
|
|
1330
|
+
}
|
|
1331
|
+
|
|
1332
|
+
return (
|
|
1333
|
+
<div>
|
|
1334
|
+
<p>Welcome, {currentUser.sub}!</p>
|
|
1335
|
+
<button onClick={signOut}>Sign Out</button>
|
|
1336
|
+
</div>
|
|
1337
|
+
);
|
|
1338
|
+
}
|
|
1339
|
+
```
|
|
1340
|
+
|
|
1341
|
+
**Context Benefits:**
|
|
1172
1342
|
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1343
|
+
- **Prop Drilling Elimination**: Access authentication state without passing props
|
|
1344
|
+
- **Component Isolation**: Components can access auth state regardless of component tree depth
|
|
1345
|
+
- **Centralized State**: Single source of truth for authentication across the application
|
|
1346
|
+
- **Automatic Re-rendering**: Components automatically re-render when authentication state changes
|
|
1176
1347
|
|
|
1177
|
-
|
|
1348
|
+
### Wow Query Hooks
|
|
1178
1349
|
|
|
1179
1350
|
The Wow Query Hooks provide advanced data querying capabilities with built-in state management for conditions,
|
|
1180
1351
|
projections, sorting, pagination, and limits. These hooks are designed to work with the `@ahoo-wang/fetcher-wow` package
|
|
1181
1352
|
for complex query operations.
|
|
1182
1353
|
|
|
1183
|
-
|
|
1354
|
+
#### Basic Query Hooks
|
|
1184
1355
|
|
|
1185
|
-
|
|
1356
|
+
##### useListQuery Hook
|
|
1186
1357
|
|
|
1187
1358
|
The `useListQuery` hook manages list queries with state management for conditions, projections, sorting, and limits.
|
|
1188
1359
|
|
|
@@ -1219,7 +1390,7 @@ const MyComponent = () => {
|
|
|
1219
1390
|
};
|
|
1220
1391
|
```
|
|
1221
1392
|
|
|
1222
|
-
|
|
1393
|
+
##### Auto Execute Example
|
|
1223
1394
|
|
|
1224
1395
|
```typescript jsx
|
|
1225
1396
|
import { useListQuery } from '@ahoo-wang/fetcher-react';
|
|
@@ -1249,7 +1420,7 @@ const MyComponent = () => {
|
|
|
1249
1420
|
};
|
|
1250
1421
|
```
|
|
1251
1422
|
|
|
1252
|
-
|
|
1423
|
+
##### usePagedQuery Hook
|
|
1253
1424
|
|
|
1254
1425
|
The `usePagedQuery` hook manages paged queries with state management for conditions, projections, pagination, and
|
|
1255
1426
|
sorting.
|
|
@@ -1297,7 +1468,7 @@ const MyComponent = () => {
|
|
|
1297
1468
|
};
|
|
1298
1469
|
```
|
|
1299
1470
|
|
|
1300
|
-
|
|
1471
|
+
###### Auto Execute Example
|
|
1301
1472
|
|
|
1302
1473
|
```typescript jsx
|
|
1303
1474
|
import { usePagedQuery } from '@ahoo-wang/fetcher-react';
|
|
@@ -1337,7 +1508,7 @@ const MyComponent = () => {
|
|
|
1337
1508
|
};
|
|
1338
1509
|
```
|
|
1339
1510
|
|
|
1340
|
-
|
|
1511
|
+
##### useSingleQuery Hook
|
|
1341
1512
|
|
|
1342
1513
|
The `useSingleQuery` hook manages single item queries with state management for conditions, projections, and sorting.
|
|
1343
1514
|
|
|
@@ -1370,7 +1541,7 @@ const MyComponent = () => {
|
|
|
1370
1541
|
};
|
|
1371
1542
|
```
|
|
1372
1543
|
|
|
1373
|
-
|
|
1544
|
+
###### Auto Execute Example
|
|
1374
1545
|
|
|
1375
1546
|
```typescript jsx
|
|
1376
1547
|
import { useSingleQuery } from '@ahoo-wang/fetcher-react';
|
|
@@ -1395,7 +1566,7 @@ const MyComponent = () => {
|
|
|
1395
1566
|
};
|
|
1396
1567
|
```
|
|
1397
1568
|
|
|
1398
|
-
|
|
1569
|
+
##### useCountQuery Hook
|
|
1399
1570
|
|
|
1400
1571
|
The `useCountQuery` hook manages count queries with state management for conditions.
|
|
1401
1572
|
|
|
@@ -1428,7 +1599,7 @@ const MyComponent = () => {
|
|
|
1428
1599
|
};
|
|
1429
1600
|
```
|
|
1430
1601
|
|
|
1431
|
-
|
|
1602
|
+
###### Auto Execute Example
|
|
1432
1603
|
|
|
1433
1604
|
```typescript jsx
|
|
1434
1605
|
import { useCountQuery } from '@ahoo-wang/fetcher-react';
|
|
@@ -1453,9 +1624,99 @@ const MyComponent = () => {
|
|
|
1453
1624
|
};
|
|
1454
1625
|
```
|
|
1455
1626
|
|
|
1456
|
-
|
|
1627
|
+
##### useListStreamQuery Hook
|
|
1628
|
+
|
|
1629
|
+
The `useListStreamQuery` hook manages list stream queries that return a readable stream of server-sent events.
|
|
1630
|
+
|
|
1631
|
+
```typescript jsx
|
|
1632
|
+
import { useListStreamQuery } from '@ahoo-wang/fetcher-react';
|
|
1633
|
+
|
|
1634
|
+
const MyComponent = () => {
|
|
1635
|
+
const { result, loading, error, execute, setCondition } = useListStreamQuery({
|
|
1636
|
+
initialQuery: { condition: {}, projection: {}, sort: [], limit: 100 },
|
|
1637
|
+
execute: async (listQuery) => {
|
|
1638
|
+
// Your stream fetching logic here
|
|
1639
|
+
return fetchListStream(listQuery);
|
|
1640
|
+
},
|
|
1641
|
+
});
|
|
1642
|
+
|
|
1643
|
+
useEffect(() => {
|
|
1644
|
+
if (result) {
|
|
1645
|
+
const reader = result.getReader();
|
|
1646
|
+
const readStream = async () => {
|
|
1647
|
+
try {
|
|
1648
|
+
while (true) {
|
|
1649
|
+
const { done, value } = await reader.read();
|
|
1650
|
+
if (done) break;
|
|
1651
|
+
console.log('Received:', value);
|
|
1652
|
+
// Process the stream event
|
|
1653
|
+
}
|
|
1654
|
+
} catch (error) {
|
|
1655
|
+
console.error('Stream error:', error);
|
|
1656
|
+
}
|
|
1657
|
+
};
|
|
1658
|
+
readStream();
|
|
1659
|
+
}
|
|
1660
|
+
}, [result]);
|
|
1661
|
+
|
|
1662
|
+
if (loading) return <div>Loading...</div>;
|
|
1663
|
+
if (error) return <div>Error: {error.message}</div>;
|
|
1664
|
+
|
|
1665
|
+
return (
|
|
1666
|
+
<div>
|
|
1667
|
+
<button onClick={execute}>Start Stream</button>
|
|
1668
|
+
</div>
|
|
1669
|
+
);
|
|
1670
|
+
};
|
|
1671
|
+
```
|
|
1672
|
+
|
|
1673
|
+
###### Auto Execute Example
|
|
1674
|
+
|
|
1675
|
+
```typescript jsx
|
|
1676
|
+
import { useListStreamQuery } from '@ahoo-wang/fetcher-react';
|
|
1677
|
+
|
|
1678
|
+
const MyComponent = () => {
|
|
1679
|
+
const { result, loading, error, execute, setCondition } = useListStreamQuery({
|
|
1680
|
+
initialQuery: { condition: {}, projection: {}, sort: [], limit: 100 },
|
|
1681
|
+
execute: async (listQuery) => fetchListStream(listQuery),
|
|
1682
|
+
autoExecute: true, // Automatically execute on component mount
|
|
1683
|
+
});
|
|
1684
|
+
|
|
1685
|
+
useEffect(() => {
|
|
1686
|
+
if (result) {
|
|
1687
|
+
const reader = result.getReader();
|
|
1688
|
+
const readStream = async () => {
|
|
1689
|
+
try {
|
|
1690
|
+
while (true) {
|
|
1691
|
+
const { done, value } = await reader.read();
|
|
1692
|
+
if (done) break;
|
|
1693
|
+
console.log('Received:', value);
|
|
1694
|
+
// Process the stream event
|
|
1695
|
+
}
|
|
1696
|
+
} catch (error) {
|
|
1697
|
+
console.error('Stream error:', error);
|
|
1698
|
+
}
|
|
1699
|
+
};
|
|
1700
|
+
readStream();
|
|
1701
|
+
}
|
|
1702
|
+
}, [result]);
|
|
1703
|
+
|
|
1704
|
+
// The query will execute automatically when the component mounts
|
|
1705
|
+
|
|
1706
|
+
if (loading) return <div>Loading...</div>;
|
|
1707
|
+
if (error) return <div>Error: {error.message}</div>;
|
|
1708
|
+
|
|
1709
|
+
return (
|
|
1710
|
+
<div>
|
|
1711
|
+
{/* Stream is already started automatically */}
|
|
1712
|
+
</div>
|
|
1713
|
+
);
|
|
1714
|
+
};
|
|
1715
|
+
```
|
|
1716
|
+
|
|
1717
|
+
#### Fetcher Query Hooks
|
|
1457
1718
|
|
|
1458
|
-
|
|
1719
|
+
##### useFetcherCountQuery Hook
|
|
1459
1720
|
|
|
1460
1721
|
The `useFetcherCountQuery` hook is a specialized React hook for performing count queries using the Fetcher library. It is designed for scenarios where you need to retrieve the count of records that match a specific condition, returning a number representing the count.
|
|
1461
1722
|
|
|
@@ -1479,7 +1740,7 @@ function UserCountComponent() {
|
|
|
1479
1740
|
}
|
|
1480
1741
|
```
|
|
1481
1742
|
|
|
1482
|
-
|
|
1743
|
+
###### Auto Execute Example
|
|
1483
1744
|
|
|
1484
1745
|
```typescript jsx
|
|
1485
1746
|
import { useFetcherCountQuery } from '@ahoo-wang/fetcher-react';
|
|
@@ -1500,7 +1761,7 @@ const MyComponent = () => {
|
|
|
1500
1761
|
};
|
|
1501
1762
|
```
|
|
1502
1763
|
|
|
1503
|
-
|
|
1764
|
+
##### useFetcherPagedQuery Hook
|
|
1504
1765
|
|
|
1505
1766
|
The `useFetcherPagedQuery` hook is a specialized React hook for performing paged queries using the Fetcher library. It is designed for scenarios where you need to retrieve paginated data that matches a query condition, returning a PagedList containing the items for the current page along with pagination metadata.
|
|
1506
1767
|
|
|
@@ -1569,7 +1830,7 @@ function UserListComponent() {
|
|
|
1569
1830
|
}
|
|
1570
1831
|
```
|
|
1571
1832
|
|
|
1572
|
-
|
|
1833
|
+
###### Auto Execute Example
|
|
1573
1834
|
|
|
1574
1835
|
```typescript jsx
|
|
1575
1836
|
import { useFetcherPagedQuery } from '@ahoo-wang/fetcher-react';
|
|
@@ -1605,7 +1866,7 @@ const MyComponent = () => {
|
|
|
1605
1866
|
};
|
|
1606
1867
|
```
|
|
1607
1868
|
|
|
1608
|
-
|
|
1869
|
+
##### useFetcherListQuery Hook
|
|
1609
1870
|
|
|
1610
1871
|
The `useFetcherListQuery` hook is a specialized React hook for performing list queries using the Fetcher library. It is designed for fetching lists of items with support for filtering, sorting, and pagination through the ListQuery type, returning an array of results.
|
|
1611
1872
|
|
|
@@ -1666,7 +1927,7 @@ function UserListComponent() {
|
|
|
1666
1927
|
}
|
|
1667
1928
|
```
|
|
1668
1929
|
|
|
1669
|
-
|
|
1930
|
+
###### Auto Execute Example
|
|
1670
1931
|
|
|
1671
1932
|
```typescript jsx
|
|
1672
1933
|
import { useFetcherListQuery } from '@ahoo-wang/fetcher-react';
|
|
@@ -1701,7 +1962,7 @@ const MyComponent = () => {
|
|
|
1701
1962
|
};
|
|
1702
1963
|
```
|
|
1703
1964
|
|
|
1704
|
-
|
|
1965
|
+
##### useFetcherListStreamQuery Hook
|
|
1705
1966
|
|
|
1706
1967
|
The `useFetcherListStreamQuery` hook is a specialized React hook for performing list stream queries using the Fetcher library with server-sent events. It is designed for scenarios where you need to retrieve a stream of data that matches a list query condition, returning a ReadableStream of JSON server-sent events for real-time data streaming.
|
|
1707
1968
|
|
|
@@ -1764,7 +2025,7 @@ function UserStreamComponent() {
|
|
|
1764
2025
|
}
|
|
1765
2026
|
```
|
|
1766
2027
|
|
|
1767
|
-
|
|
2028
|
+
###### Auto Execute Example
|
|
1768
2029
|
|
|
1769
2030
|
```typescript jsx
|
|
1770
2031
|
import { useFetcherListStreamQuery } from '@ahoo-wang/fetcher-react';
|
|
@@ -1820,7 +2081,7 @@ const MyComponent = () => {
|
|
|
1820
2081
|
};
|
|
1821
2082
|
```
|
|
1822
2083
|
|
|
1823
|
-
|
|
2084
|
+
##### useFetcherSingleQuery Hook
|
|
1824
2085
|
|
|
1825
2086
|
The `useFetcherSingleQuery` hook is a specialized React hook for performing single item queries using the Fetcher library. It is designed for fetching a single item with support for filtering and sorting through the SingleQuery type, returning a single result item.
|
|
1826
2087
|
|
|
@@ -1864,7 +2125,7 @@ function UserProfileComponent({ userId }: { userId: string }) {
|
|
|
1864
2125
|
}
|
|
1865
2126
|
```
|
|
1866
2127
|
|
|
1867
|
-
|
|
2128
|
+
###### Auto Execute Example
|
|
1868
2129
|
|
|
1869
2130
|
```typescript jsx
|
|
1870
2131
|
import { useFetcherSingleQuery } from '@ahoo-wang/fetcher-react';
|
|
@@ -1896,103 +2157,11 @@ const MyComponent = () => {
|
|
|
1896
2157
|
};
|
|
1897
2158
|
```
|
|
1898
2159
|
|
|
1899
|
-
### Stream Query Hooks
|
|
1900
|
-
|
|
1901
|
-
#### useListStreamQuery Hook
|
|
1902
|
-
|
|
1903
|
-
The `useListStreamQuery` hook manages list stream queries that return a readable stream of server-sent events.
|
|
1904
|
-
|
|
1905
|
-
```typescript jsx
|
|
1906
|
-
import { useListStreamQuery } from '@ahoo-wang/fetcher-react';
|
|
1907
|
-
|
|
1908
|
-
const MyComponent = () => {
|
|
1909
|
-
const { result, loading, error, execute, setCondition } = useListStreamQuery({
|
|
1910
|
-
initialQuery: { condition: {}, projection: {}, sort: [], limit: 100 },
|
|
1911
|
-
execute: async (listQuery) => {
|
|
1912
|
-
// Your stream fetching logic here
|
|
1913
|
-
return fetchListStream(listQuery);
|
|
1914
|
-
},
|
|
1915
|
-
});
|
|
1916
|
-
|
|
1917
|
-
useEffect(() => {
|
|
1918
|
-
if (result) {
|
|
1919
|
-
const reader = result.getReader();
|
|
1920
|
-
const readStream = async () => {
|
|
1921
|
-
try {
|
|
1922
|
-
while (true) {
|
|
1923
|
-
const { done, value } = await reader.read();
|
|
1924
|
-
if (done) break;
|
|
1925
|
-
console.log('Received:', value);
|
|
1926
|
-
// Process the stream event
|
|
1927
|
-
}
|
|
1928
|
-
} catch (error) {
|
|
1929
|
-
console.error('Stream error:', error);
|
|
1930
|
-
}
|
|
1931
|
-
};
|
|
1932
|
-
readStream();
|
|
1933
|
-
}
|
|
1934
|
-
}, [result]);
|
|
1935
|
-
|
|
1936
|
-
if (loading) return <div>Loading...</div>;
|
|
1937
|
-
if (error) return <div>Error: {error.message}</div>;
|
|
1938
|
-
|
|
1939
|
-
return (
|
|
1940
|
-
<div>
|
|
1941
|
-
<button onClick={execute}>Start Stream</button>
|
|
1942
|
-
</div>
|
|
1943
|
-
);
|
|
1944
|
-
};
|
|
1945
|
-
```
|
|
1946
|
-
|
|
1947
|
-
#### Auto Execute Example
|
|
1948
|
-
|
|
1949
|
-
```typescript jsx
|
|
1950
|
-
import { useListStreamQuery } from '@ahoo-wang/fetcher-react';
|
|
1951
|
-
|
|
1952
|
-
const MyComponent = () => {
|
|
1953
|
-
const { result, loading, error, execute, setCondition } = useListStreamQuery({
|
|
1954
|
-
initialQuery: { condition: {}, projection: {}, sort: [], limit: 100 },
|
|
1955
|
-
execute: async (listQuery) => fetchListStream(listQuery),
|
|
1956
|
-
autoExecute: true, // Automatically execute on component mount
|
|
1957
|
-
});
|
|
1958
|
-
|
|
1959
|
-
useEffect(() => {
|
|
1960
|
-
if (result) {
|
|
1961
|
-
const reader = result.getReader();
|
|
1962
|
-
const readStream = async () => {
|
|
1963
|
-
try {
|
|
1964
|
-
while (true) {
|
|
1965
|
-
const { done, value } = await reader.read();
|
|
1966
|
-
if (done) break;
|
|
1967
|
-
console.log('Received:', value);
|
|
1968
|
-
// Process the stream event
|
|
1969
|
-
}
|
|
1970
|
-
} catch (error) {
|
|
1971
|
-
console.error('Stream error:', error);
|
|
1972
|
-
}
|
|
1973
|
-
};
|
|
1974
|
-
readStream();
|
|
1975
|
-
}
|
|
1976
|
-
}, [result]);
|
|
1977
|
-
|
|
1978
|
-
// The query will execute automatically when the component mounts
|
|
1979
|
-
|
|
1980
|
-
if (loading) return <div>Loading...</div>;
|
|
1981
|
-
if (error) return <div>Error: {error.message}</div>;
|
|
1982
|
-
|
|
1983
|
-
return (
|
|
1984
|
-
<div>
|
|
1985
|
-
{/* Stream is already started automatically */}
|
|
1986
|
-
</div>
|
|
1987
|
-
);
|
|
1988
|
-
};
|
|
1989
|
-
```
|
|
1990
|
-
|
|
1991
2160
|
## Best Practices
|
|
1992
2161
|
|
|
1993
2162
|
### Performance Optimization
|
|
1994
2163
|
|
|
1995
|
-
- Use `autoExecute:
|
|
2164
|
+
- Use `autoExecute: false` when you need to control when queries execute
|
|
1996
2165
|
- Leverage `setQuery` for query updates when `autoExecute` is enabled to trigger automatic re-execution
|
|
1997
2166
|
- Memoize expensive computations in your `execute` functions
|
|
1998
2167
|
|
|
@@ -2070,7 +2239,7 @@ import { Component, ErrorInfo, ReactNode } from 'react';
|
|
|
2070
2239
|
class FetchErrorBoundary extends Component<
|
|
2071
2240
|
{ children: ReactNode; fallback?: ReactNode },
|
|
2072
2241
|
{ hasError: boolean; error?: Error }
|
|
2073
|
-
> {
|
|
2242
|
+
> {
|
|
2074
2243
|
constructor(props: { children: ReactNode; fallback?: ReactNode }) {
|
|
2075
2244
|
super(props);
|
|
2076
2245
|
this.state = { hasError: false };
|
|
@@ -2852,6 +3021,96 @@ An object implementing `UseRefsReturn<T>` with:
|
|
|
2852
3021
|
- `RefKey = string | number | symbol`
|
|
2853
3022
|
- `UseRefsReturn<T> extends Iterable<[RefKey, T]>`
|
|
2854
3023
|
|
|
3024
|
+
### useQuery
|
|
3025
|
+
|
|
3026
|
+
```typescript
|
|
3027
|
+
function useQuery<Q, R, E = FetcherError>(
|
|
3028
|
+
options: UseQueryOptions<Q, R, E>,
|
|
3029
|
+
): UseQueryReturn<Q, R, E>;
|
|
3030
|
+
```
|
|
3031
|
+
|
|
3032
|
+
A React hook for managing query-based asynchronous operations with automatic state management and execution control.
|
|
3033
|
+
|
|
3034
|
+
**Type Parameters:**
|
|
3035
|
+
|
|
3036
|
+
- `Q`: The type of the query parameters
|
|
3037
|
+
- `R`: The type of the result value
|
|
3038
|
+
- `E`: The type of the error value (defaults to FetcherError)
|
|
3039
|
+
|
|
3040
|
+
**Parameters:**
|
|
3041
|
+
|
|
3042
|
+
- `options`: Configuration options for the query
|
|
3043
|
+
- `initialQuery`: The initial query parameters
|
|
3044
|
+
- `execute`: Function to execute the query with given parameters and optional attributes
|
|
3045
|
+
- `autoExecute?`: Whether to automatically execute the query on mount and when query changes
|
|
3046
|
+
- All options from `UseExecutePromiseOptions`
|
|
3047
|
+
|
|
3048
|
+
**Returns:**
|
|
3049
|
+
|
|
3050
|
+
An object containing the query state and control functions:
|
|
3051
|
+
|
|
3052
|
+
- `loading`: Boolean indicating if the query is currently executing
|
|
3053
|
+
- `result`: The resolved value of the query
|
|
3054
|
+
- `error`: Any error that occurred during execution
|
|
3055
|
+
- `status`: Current execution status
|
|
3056
|
+
- `execute`: Function to execute the query with current parameters
|
|
3057
|
+
- `reset`: Function to reset the promise state
|
|
3058
|
+
- `abort`: Function to abort the current operation
|
|
3059
|
+
- `getQuery`: Function to retrieve the current query parameters
|
|
3060
|
+
- `setQuery`: Function to update the query parameters
|
|
3061
|
+
|
|
3062
|
+
### useQueryState
|
|
3063
|
+
|
|
3064
|
+
```typescript
|
|
3065
|
+
function useQueryState<Q>(
|
|
3066
|
+
options: UseQueryStateOptions<Q>,
|
|
3067
|
+
): UseQueryStateReturn<Q>;
|
|
3068
|
+
```
|
|
3069
|
+
|
|
3070
|
+
A React hook for managing query state with automatic execution capabilities.
|
|
3071
|
+
|
|
3072
|
+
**Type Parameters:**
|
|
3073
|
+
|
|
3074
|
+
- `Q`: The type of the query parameters
|
|
3075
|
+
|
|
3076
|
+
**Parameters:**
|
|
3077
|
+
|
|
3078
|
+
- `options`: Configuration options for the hook
|
|
3079
|
+
- `initialQuery`: The initial query parameters to be stored and managed
|
|
3080
|
+
- `autoExecute?`: Whether to automatically execute when the query changes or on component mount
|
|
3081
|
+
- `execute`: Function to execute with the current query parameters
|
|
3082
|
+
|
|
3083
|
+
**Returns:**
|
|
3084
|
+
|
|
3085
|
+
An object containing:
|
|
3086
|
+
|
|
3087
|
+
- `getQuery`: Function to retrieve the current query parameters
|
|
3088
|
+
- `setQuery`: Function to update the query parameters. Triggers execution if autoExecute is true
|
|
3089
|
+
|
|
3090
|
+
### useMounted
|
|
3091
|
+
|
|
3092
|
+
```typescript
|
|
3093
|
+
function useMounted(): () => boolean;
|
|
3094
|
+
```
|
|
3095
|
+
|
|
3096
|
+
A React hook that returns a function to check if the component is still mounted.
|
|
3097
|
+
|
|
3098
|
+
**Returns:**
|
|
3099
|
+
|
|
3100
|
+
A function that returns `true` if the component is still mounted, `false` otherwise.
|
|
3101
|
+
|
|
3102
|
+
### useForceUpdate
|
|
3103
|
+
|
|
3104
|
+
```typescript
|
|
3105
|
+
function useForceUpdate(): () => void;
|
|
3106
|
+
```
|
|
3107
|
+
|
|
3108
|
+
A React hook that returns a function to force a component to re-render.
|
|
3109
|
+
|
|
3110
|
+
**Returns:**
|
|
3111
|
+
|
|
3112
|
+
A function that forces the component to re-render when called.
|
|
3113
|
+
|
|
2855
3114
|
### useEventSubscription
|
|
2856
3115
|
|
|
2857
3116
|
```typescript
|
|
@@ -3013,7 +3272,7 @@ A React hook for managing list queries with state management for conditions, pro
|
|
|
3013
3272
|
**Parameters:**
|
|
3014
3273
|
|
|
3015
3274
|
- `options`: Configuration options including initialQuery and list function
|
|
3016
|
-
- `autoExecute`: Whether to automatically execute the query on component mount (defaults to
|
|
3275
|
+
- `autoExecute`: Whether to automatically execute the query on component mount (defaults to true)
|
|
3017
3276
|
|
|
3018
3277
|
**Returns:**
|
|
3019
3278
|
|
|
@@ -3038,7 +3297,7 @@ A React hook for managing paged queries with state management for conditions, pr
|
|
|
3038
3297
|
**Parameters:**
|
|
3039
3298
|
|
|
3040
3299
|
- `options`: Configuration options including initialQuery and query function
|
|
3041
|
-
- `autoExecute`: Whether to automatically execute the query on component mount (defaults to
|
|
3300
|
+
- `autoExecute`: Whether to automatically execute the query on component mount (defaults to true)
|
|
3042
3301
|
|
|
3043
3302
|
**Returns:**
|
|
3044
3303
|
|
|
@@ -3063,7 +3322,7 @@ A React hook for managing single queries with state management for conditions, p
|
|
|
3063
3322
|
**Parameters:**
|
|
3064
3323
|
|
|
3065
3324
|
- `options`: Configuration options including initialQuery and query function
|
|
3066
|
-
- `autoExecute`: Whether to automatically execute the query on component mount (defaults to
|
|
3325
|
+
- `autoExecute`: Whether to automatically execute the query on component mount (defaults to true)
|
|
3067
3326
|
|
|
3068
3327
|
**Returns:**
|
|
3069
3328
|
|
|
@@ -3087,7 +3346,7 @@ A React hook for managing count queries with state management for conditions.
|
|
|
3087
3346
|
**Parameters:**
|
|
3088
3347
|
|
|
3089
3348
|
- `options`: Configuration options including initialQuery and execute function
|
|
3090
|
-
- `autoExecute`: Whether to automatically execute the query on component mount (defaults to
|
|
3349
|
+
- `autoExecute`: Whether to automatically execute the query on component mount (defaults to true)
|
|
3091
3350
|
|
|
3092
3351
|
**Returns:**
|
|
3093
3352
|
|
|
@@ -3113,7 +3372,7 @@ A React hook for performing count queries using the Fetcher library. It wraps th
|
|
|
3113
3372
|
- `options`: Configuration options for the count query, including the condition, fetcher instance, and other query settings
|
|
3114
3373
|
- `url`: The URL to fetch the count from
|
|
3115
3374
|
- `initialQuery`: The initial condition for the count query
|
|
3116
|
-
- `autoExecute`: Whether to automatically execute the query on component mount (defaults to
|
|
3375
|
+
- `autoExecute`: Whether to automatically execute the query on component mount (defaults to true)
|
|
3117
3376
|
|
|
3118
3377
|
**Returns:**
|
|
3119
3378
|
|
|
@@ -3144,7 +3403,7 @@ A React hook for performing paged queries using the Fetcher library. It wraps th
|
|
|
3144
3403
|
- `options`: Configuration options for the paged query, including the paged query parameters, fetcher instance, and other query settings
|
|
3145
3404
|
- `url`: The URL to fetch the paged data from
|
|
3146
3405
|
- `initialQuery`: The initial paged query configuration
|
|
3147
|
-
- `autoExecute`: Whether to automatically execute the query on component mount (defaults to
|
|
3406
|
+
- `autoExecute`: Whether to automatically execute the query on component mount (defaults to true)
|
|
3148
3407
|
|
|
3149
3408
|
**Returns:**
|
|
3150
3409
|
|
|
@@ -3175,7 +3434,7 @@ A React hook for executing list queries using the fetcher library within the wow
|
|
|
3175
3434
|
- `options`: Configuration options for the list query, including the list query parameters, fetcher instance, and other query settings
|
|
3176
3435
|
- `url`: The URL to fetch the list data from
|
|
3177
3436
|
- `initialQuery`: The initial list query configuration
|
|
3178
|
-
- `autoExecute`: Whether to automatically execute the query on component mount (defaults to
|
|
3437
|
+
- `autoExecute`: Whether to automatically execute the query on component mount (defaults to true)
|
|
3179
3438
|
|
|
3180
3439
|
**Returns:**
|
|
3181
3440
|
|
|
@@ -3206,7 +3465,7 @@ A React hook for performing list stream queries using the Fetcher library with s
|
|
|
3206
3465
|
- `options`: Configuration options for the list stream query, including the list query parameters, fetcher instance, and other query settings
|
|
3207
3466
|
- `url`: The URL to fetch the stream data from
|
|
3208
3467
|
- `initialQuery`: The initial list query configuration
|
|
3209
|
-
- `autoExecute`: Whether to automatically execute the query on component mount (defaults to
|
|
3468
|
+
- `autoExecute`: Whether to automatically execute the query on component mount (defaults to true)
|
|
3210
3469
|
|
|
3211
3470
|
**Returns:**
|
|
3212
3471
|
|
|
@@ -3237,7 +3496,7 @@ A React hook for executing single item queries using the fetcher library within
|
|
|
3237
3496
|
- `options`: Configuration options for the single query, including the single query parameters, fetcher instance, and other query settings
|
|
3238
3497
|
- `url`: The URL to fetch the single item from
|
|
3239
3498
|
- `initialQuery`: The initial single query configuration
|
|
3240
|
-
- `autoExecute`: Whether to automatically execute the query on component mount (defaults to
|
|
3499
|
+
- `autoExecute`: Whether to automatically execute the query on component mount (defaults to true)
|
|
3241
3500
|
|
|
3242
3501
|
**Returns:**
|
|
3243
3502
|
|
|
@@ -3267,7 +3526,7 @@ Returns a readable stream of JSON server-sent events.
|
|
|
3267
3526
|
**Parameters:**
|
|
3268
3527
|
|
|
3269
3528
|
- `options`: Configuration options including initialQuery and listStream function
|
|
3270
|
-
- `autoExecute`: Whether to automatically execute the query on component mount (defaults to
|
|
3529
|
+
- `autoExecute`: Whether to automatically execute the query on component mount (defaults to true)
|
|
3271
3530
|
|
|
3272
3531
|
**Returns:**
|
|
3273
3532
|
|