@ahoo-wang/fetcher-react 2.8.8 → 2.9.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 +499 -27
- package/dist/index.es.js +66 -62
- 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/storage/useKeyStorage.d.ts.map +1 -1
- package/package.json +2 -3
package/README.md
CHANGED
|
@@ -26,18 +26,18 @@ robust data fetching capabilities.
|
|
|
26
26
|
|
|
27
27
|
- [Installation](#installation)
|
|
28
28
|
- [Usage](#usage)
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
29
|
+
- [useFetcher Hook](#usefetcher-hook)
|
|
30
|
+
- [useExecutePromise Hook](#useexecutepromise-hook)
|
|
31
|
+
- [usePromiseState Hook](#usepromisestate-hook)
|
|
32
|
+
- [useRequestId Hook](#userequestid-hook)
|
|
33
|
+
- [useLatest Hook](#uselatest-hook)
|
|
34
|
+
- [useKeyStorage Hook](#usekeystorage-hook)
|
|
35
|
+
- [Wow Query Hooks](#wow-query-hooks)
|
|
36
|
+
- [useListQuery Hook](#uselistquery-hook)
|
|
37
|
+
- [usePagedQuery Hook](#usepagedquery-hook)
|
|
38
|
+
- [useSingleQuery Hook](#usesinglequery-hook)
|
|
39
|
+
- [useCountQuery Hook](#usecountquery-hook)
|
|
40
|
+
- [useListStreamQuery Hook](#useliststreamquery-hook)
|
|
41
41
|
- [Best Practices](#best-practices)
|
|
42
42
|
- [API Reference](#api-reference)
|
|
43
43
|
- [License](#license)
|
|
@@ -724,6 +724,478 @@ const MyComponent = () => {
|
|
|
724
724
|
- Use `useKeyStorage` for persistent client-side data
|
|
725
725
|
- Implement optimistic updates for better UX
|
|
726
726
|
|
|
727
|
+
## 🚀 Advanced Usage Examples
|
|
728
|
+
|
|
729
|
+
### Custom Hook Composition
|
|
730
|
+
|
|
731
|
+
Create reusable hooks by composing multiple fetcher-react hooks:
|
|
732
|
+
|
|
733
|
+
```typescript jsx
|
|
734
|
+
import { useFetcher, usePromiseState, useLatest } from '@ahoo-wang/fetcher-react';
|
|
735
|
+
import { useCallback, useEffect } from 'react';
|
|
736
|
+
|
|
737
|
+
function useUserProfile(userId: string) {
|
|
738
|
+
const latestUserId = useLatest(userId);
|
|
739
|
+
const { loading, result: profile, error, execute } = useFetcher();
|
|
740
|
+
|
|
741
|
+
const fetchProfile = useCallback(() => {
|
|
742
|
+
execute({
|
|
743
|
+
url: `/api/users/${latestUserId.current}`,
|
|
744
|
+
method: 'GET'
|
|
745
|
+
});
|
|
746
|
+
}, [execute, latestUserId]);
|
|
747
|
+
|
|
748
|
+
useEffect(() => {
|
|
749
|
+
if (userId) {
|
|
750
|
+
fetchProfile();
|
|
751
|
+
}
|
|
752
|
+
}, [userId, fetchProfile]);
|
|
753
|
+
|
|
754
|
+
return { profile, loading, error, refetch: fetchProfile };
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
// Usage
|
|
758
|
+
function UserProfile({ userId }: { userId: string }) {
|
|
759
|
+
const { profile, loading, error, refetch } = useUserProfile(userId);
|
|
760
|
+
|
|
761
|
+
if (loading) return <div>Loading...</div>;
|
|
762
|
+
if (error) return <div>Error: {error.message}</div>;
|
|
763
|
+
|
|
764
|
+
return (
|
|
765
|
+
<div>
|
|
766
|
+
<h2>{profile?.name}</h2>
|
|
767
|
+
<button onClick={refetch}>Refresh</button>
|
|
768
|
+
</div>
|
|
769
|
+
);
|
|
770
|
+
}
|
|
771
|
+
```
|
|
772
|
+
|
|
773
|
+
### Error Boundaries Integration
|
|
774
|
+
|
|
775
|
+
Integrate with React Error Boundaries for better error handling:
|
|
776
|
+
|
|
777
|
+
```typescript jsx
|
|
778
|
+
import { Component, ErrorInfo, ReactNode } from 'react';
|
|
779
|
+
|
|
780
|
+
class FetchErrorBoundary extends Component<
|
|
781
|
+
{ children: ReactNode; fallback?: ReactNode },
|
|
782
|
+
{ hasError: boolean; error?: Error }
|
|
783
|
+
> {
|
|
784
|
+
constructor(props: { children: ReactNode; fallback?: ReactNode }) {
|
|
785
|
+
super(props);
|
|
786
|
+
this.state = { hasError: false };
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
static getDerivedStateFromError(error: Error) {
|
|
790
|
+
return { hasError: true, error };
|
|
791
|
+
}
|
|
792
|
+
|
|
793
|
+
componentDidCatch(error: Error, errorInfo: ErrorInfo) {
|
|
794
|
+
console.error('Fetch error boundary caught an error:', error, errorInfo);
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
render() {
|
|
798
|
+
if (this.state.hasError) {
|
|
799
|
+
return this.props.fallback || <div>Something went wrong.</div>;
|
|
800
|
+
}
|
|
801
|
+
|
|
802
|
+
return this.props.children;
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
|
|
806
|
+
// Usage with hooks
|
|
807
|
+
function DataComponent() {
|
|
808
|
+
const { result, loading, error, execute } = useFetcher();
|
|
809
|
+
|
|
810
|
+
// Error will be caught by boundary if thrown
|
|
811
|
+
if (error) {
|
|
812
|
+
throw error;
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
return (
|
|
816
|
+
<div>
|
|
817
|
+
{loading ? 'Loading...' : JSON.stringify(result)}
|
|
818
|
+
</div>
|
|
819
|
+
);
|
|
820
|
+
}
|
|
821
|
+
|
|
822
|
+
// Wrap components that use fetcher hooks
|
|
823
|
+
function App() {
|
|
824
|
+
return (
|
|
825
|
+
<FetchErrorBoundary fallback={<div>Failed to load data</div>}>
|
|
826
|
+
<DataComponent />
|
|
827
|
+
</FetchErrorBoundary>
|
|
828
|
+
);
|
|
829
|
+
}
|
|
830
|
+
```
|
|
831
|
+
|
|
832
|
+
### Suspense Integration
|
|
833
|
+
|
|
834
|
+
Use with React Suspense for better loading states:
|
|
835
|
+
|
|
836
|
+
```typescript jsx
|
|
837
|
+
import { Suspense, useState } from 'react';
|
|
838
|
+
import { useFetcher } from '@ahoo-wang/fetcher-react';
|
|
839
|
+
|
|
840
|
+
// Create a resource that throws a promise
|
|
841
|
+
function createDataResource<T>(promise: Promise<T>) {
|
|
842
|
+
let status = 'pending';
|
|
843
|
+
let result: T;
|
|
844
|
+
let error: Error;
|
|
845
|
+
|
|
846
|
+
const suspender = promise.then(
|
|
847
|
+
(data) => {
|
|
848
|
+
status = 'success';
|
|
849
|
+
result = data;
|
|
850
|
+
},
|
|
851
|
+
(err) => {
|
|
852
|
+
status = 'error';
|
|
853
|
+
error = err;
|
|
854
|
+
}
|
|
855
|
+
);
|
|
856
|
+
|
|
857
|
+
return {
|
|
858
|
+
read() {
|
|
859
|
+
if (status === 'pending') {
|
|
860
|
+
throw suspender;
|
|
861
|
+
} else if (status === 'error') {
|
|
862
|
+
throw error;
|
|
863
|
+
} else {
|
|
864
|
+
return result;
|
|
865
|
+
}
|
|
866
|
+
}
|
|
867
|
+
};
|
|
868
|
+
}
|
|
869
|
+
|
|
870
|
+
function DataComponent({ resource }: { resource: any }) {
|
|
871
|
+
const data = resource.read(); // This will throw if pending
|
|
872
|
+
return <div>{JSON.stringify(data)}</div>;
|
|
873
|
+
}
|
|
874
|
+
|
|
875
|
+
function App() {
|
|
876
|
+
const [resource, setResource] = useState<any>(null);
|
|
877
|
+
|
|
878
|
+
const handleFetch = () => {
|
|
879
|
+
const { execute } = useFetcher();
|
|
880
|
+
const promise = execute({ url: '/api/data', method: 'GET' });
|
|
881
|
+
setResource(createDataResource(promise));
|
|
882
|
+
};
|
|
883
|
+
|
|
884
|
+
return (
|
|
885
|
+
<div>
|
|
886
|
+
<button onClick={handleFetch}>Fetch Data</button>
|
|
887
|
+
<Suspense fallback={<div>Loading...</div>}>
|
|
888
|
+
{resource && <DataComponent resource={resource} />}
|
|
889
|
+
</Suspense>
|
|
890
|
+
</div>
|
|
891
|
+
);
|
|
892
|
+
}
|
|
893
|
+
```
|
|
894
|
+
|
|
895
|
+
### Performance Optimization Patterns
|
|
896
|
+
|
|
897
|
+
Advanced patterns for optimal performance:
|
|
898
|
+
|
|
899
|
+
```typescript jsx
|
|
900
|
+
import { useMemo, useCallback, useRef } from 'react';
|
|
901
|
+
import { useListQuery } from '@ahoo-wang/fetcher-react';
|
|
902
|
+
|
|
903
|
+
function OptimizedDataTable({ filters, sortBy }) {
|
|
904
|
+
// Memoize query configuration to prevent unnecessary re-executions
|
|
905
|
+
const queryConfig = useMemo(() => ({
|
|
906
|
+
condition: filters,
|
|
907
|
+
sort: [{ field: sortBy, order: 'asc' }],
|
|
908
|
+
limit: 50
|
|
909
|
+
}), [filters, sortBy]);
|
|
910
|
+
|
|
911
|
+
const { result, loading, execute, setCondition } = useListQuery({
|
|
912
|
+
initialQuery: queryConfig,
|
|
913
|
+
execute: useCallback(async (query) => {
|
|
914
|
+
// Debounce API calls
|
|
915
|
+
await new Promise(resolve => setTimeout(resolve, 300));
|
|
916
|
+
return fetchData(query);
|
|
917
|
+
}, []),
|
|
918
|
+
autoExecute: true
|
|
919
|
+
});
|
|
920
|
+
|
|
921
|
+
// Use ref to track latest filters without causing re-renders
|
|
922
|
+
const filtersRef = useRef(filters);
|
|
923
|
+
|
|
924
|
+
useEffect(() => {
|
|
925
|
+
filtersRef.current = filters;
|
|
926
|
+
});
|
|
927
|
+
|
|
928
|
+
// Debounced search
|
|
929
|
+
const debouncedSearch = useMemo(
|
|
930
|
+
() => debounce((searchTerm: string) => {
|
|
931
|
+
setCondition({ ...filtersRef.current, search: searchTerm });
|
|
932
|
+
}, 500),
|
|
933
|
+
[setCondition]
|
|
934
|
+
);
|
|
935
|
+
|
|
936
|
+
return (
|
|
937
|
+
<div>
|
|
938
|
+
<input
|
|
939
|
+
onChange={(e) => debouncedSearch(e.target.value)}
|
|
940
|
+
placeholder="Search..."
|
|
941
|
+
/>
|
|
942
|
+
{loading ? 'Loading...' : (
|
|
943
|
+
<table>
|
|
944
|
+
<tbody>
|
|
945
|
+
{result?.map(item => (
|
|
946
|
+
<tr key={item.id}>
|
|
947
|
+
<td>{item.name}</td>
|
|
948
|
+
</tr>
|
|
949
|
+
))}
|
|
950
|
+
</tbody>
|
|
951
|
+
</table>
|
|
952
|
+
)}
|
|
953
|
+
</div>
|
|
954
|
+
);
|
|
955
|
+
}
|
|
956
|
+
|
|
957
|
+
// Debounce utility
|
|
958
|
+
function debounce<T extends (...args: any[]) => any>(
|
|
959
|
+
func: T,
|
|
960
|
+
wait: number
|
|
961
|
+
): (...args: Parameters<T>) => void {
|
|
962
|
+
let timeout: NodeJS.Timeout;
|
|
963
|
+
return (...args: Parameters<T>) => {
|
|
964
|
+
clearTimeout(timeout);
|
|
965
|
+
timeout = setTimeout(() => func(...args), wait);
|
|
966
|
+
};
|
|
967
|
+
}
|
|
968
|
+
```
|
|
969
|
+
|
|
970
|
+
### Real-World Integration Examples
|
|
971
|
+
|
|
972
|
+
Complete examples showing integration with popular libraries:
|
|
973
|
+
|
|
974
|
+
#### With React Query (TanStack Query)
|
|
975
|
+
|
|
976
|
+
```typescript jsx
|
|
977
|
+
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
|
978
|
+
import { useFetcher } from '@ahoo-wang/fetcher-react';
|
|
979
|
+
|
|
980
|
+
function useUserData(userId: string) {
|
|
981
|
+
return useQuery({
|
|
982
|
+
queryKey: ['user', userId],
|
|
983
|
+
queryFn: async () => {
|
|
984
|
+
const { execute } = useFetcher();
|
|
985
|
+
const result = await execute({
|
|
986
|
+
url: `/api/users/${userId}`,
|
|
987
|
+
method: 'GET'
|
|
988
|
+
});
|
|
989
|
+
return result;
|
|
990
|
+
}
|
|
991
|
+
});
|
|
992
|
+
}
|
|
993
|
+
|
|
994
|
+
function UserProfile({ userId }: { userId: string }) {
|
|
995
|
+
const { data, isLoading, error } = useUserData(userId);
|
|
996
|
+
|
|
997
|
+
if (isLoading) return <div>Loading...</div>;
|
|
998
|
+
if (error) return <div>Error: {error.message}</div>;
|
|
999
|
+
|
|
1000
|
+
return <div>Welcome, {data.name}!</div>;
|
|
1001
|
+
}
|
|
1002
|
+
```
|
|
1003
|
+
|
|
1004
|
+
#### With Redux Toolkit
|
|
1005
|
+
|
|
1006
|
+
```typescript jsx
|
|
1007
|
+
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
|
|
1008
|
+
import { useFetcher } from '@ahoo-wang/fetcher-react';
|
|
1009
|
+
|
|
1010
|
+
const fetchUserData = createAsyncThunk(
|
|
1011
|
+
'user/fetchData',
|
|
1012
|
+
async (userId: string) => {
|
|
1013
|
+
const { execute } = useFetcher();
|
|
1014
|
+
return await execute({
|
|
1015
|
+
url: `/api/users/${userId}`,
|
|
1016
|
+
method: 'GET'
|
|
1017
|
+
});
|
|
1018
|
+
}
|
|
1019
|
+
);
|
|
1020
|
+
|
|
1021
|
+
const userSlice = createSlice({
|
|
1022
|
+
name: 'user',
|
|
1023
|
+
initialState: { data: null, loading: false, error: null },
|
|
1024
|
+
reducers: {},
|
|
1025
|
+
extraReducers: (builder) => {
|
|
1026
|
+
builder
|
|
1027
|
+
.addCase(fetchUserData.pending, (state) => {
|
|
1028
|
+
state.loading = true;
|
|
1029
|
+
})
|
|
1030
|
+
.addCase(fetchUserData.fulfilled, (state, action) => {
|
|
1031
|
+
state.loading = false;
|
|
1032
|
+
state.data = action.payload;
|
|
1033
|
+
})
|
|
1034
|
+
.addCase(fetchUserData.rejected, (state, action) => {
|
|
1035
|
+
state.loading = false;
|
|
1036
|
+
state.error = action.error.message;
|
|
1037
|
+
});
|
|
1038
|
+
}
|
|
1039
|
+
});
|
|
1040
|
+
|
|
1041
|
+
function UserComponent({ userId }: { userId: string }) {
|
|
1042
|
+
const dispatch = useDispatch();
|
|
1043
|
+
const { data, loading, error } = useSelector((state) => state.user);
|
|
1044
|
+
|
|
1045
|
+
useEffect(() => {
|
|
1046
|
+
dispatch(fetchUserData(userId));
|
|
1047
|
+
}, [userId, dispatch]);
|
|
1048
|
+
|
|
1049
|
+
if (loading) return <div>Loading...</div>;
|
|
1050
|
+
if (error) return <div>Error: {error}</div>;
|
|
1051
|
+
|
|
1052
|
+
return <div>{data?.name}</div>;
|
|
1053
|
+
}
|
|
1054
|
+
```
|
|
1055
|
+
|
|
1056
|
+
#### With Zustand
|
|
1057
|
+
|
|
1058
|
+
```typescript jsx
|
|
1059
|
+
import { create } from 'zustand';
|
|
1060
|
+
import { useFetcher } from '@ahoo-wang/fetcher-react';
|
|
1061
|
+
|
|
1062
|
+
interface UserStore {
|
|
1063
|
+
user: any;
|
|
1064
|
+
loading: boolean;
|
|
1065
|
+
error: string | null;
|
|
1066
|
+
fetchUser: (userId: string) => Promise<void>;
|
|
1067
|
+
}
|
|
1068
|
+
|
|
1069
|
+
const useUserStore = create<UserStore>((set) => ({
|
|
1070
|
+
user: null,
|
|
1071
|
+
loading: false,
|
|
1072
|
+
error: null,
|
|
1073
|
+
fetchUser: async (userId) => {
|
|
1074
|
+
set({ loading: true, error: null });
|
|
1075
|
+
try {
|
|
1076
|
+
const { execute } = useFetcher();
|
|
1077
|
+
const user = await execute({
|
|
1078
|
+
url: `/api/users/${userId}`,
|
|
1079
|
+
method: 'GET'
|
|
1080
|
+
});
|
|
1081
|
+
set({ user, loading: false });
|
|
1082
|
+
} catch (error) {
|
|
1083
|
+
set({ error: error.message, loading: false });
|
|
1084
|
+
}
|
|
1085
|
+
}
|
|
1086
|
+
}));
|
|
1087
|
+
|
|
1088
|
+
function UserComponent({ userId }: { userId: string }) {
|
|
1089
|
+
const { user, loading, error, fetchUser } = useUserStore();
|
|
1090
|
+
|
|
1091
|
+
useEffect(() => {
|
|
1092
|
+
fetchUser(userId);
|
|
1093
|
+
}, [userId, fetchUser]);
|
|
1094
|
+
|
|
1095
|
+
if (loading) return <div>Loading...</div>;
|
|
1096
|
+
if (error) return <div>Error: {error}</div>;
|
|
1097
|
+
|
|
1098
|
+
return <div>{user?.name}</div>;
|
|
1099
|
+
}
|
|
1100
|
+
```
|
|
1101
|
+
|
|
1102
|
+
### Testing Patterns
|
|
1103
|
+
|
|
1104
|
+
Comprehensive testing examples for hooks:
|
|
1105
|
+
|
|
1106
|
+
```typescript jsx
|
|
1107
|
+
import { renderHook, act, waitFor } from '@testing-library/react';
|
|
1108
|
+
import { useFetcher, useListQuery } from '@ahoo-wang/fetcher-react';
|
|
1109
|
+
|
|
1110
|
+
// Mock fetcher
|
|
1111
|
+
jest.mock('@ahoo-wang/fetcher', () => ({
|
|
1112
|
+
Fetcher: jest.fn().mockImplementation(() => ({
|
|
1113
|
+
request: jest.fn(),
|
|
1114
|
+
})),
|
|
1115
|
+
}));
|
|
1116
|
+
|
|
1117
|
+
describe('useFetcher', () => {
|
|
1118
|
+
it('should handle successful fetch', async () => {
|
|
1119
|
+
const mockData = { id: 1, name: 'Test' };
|
|
1120
|
+
const mockFetcher = { request: jest.fn().mockResolvedValue(mockData) };
|
|
1121
|
+
|
|
1122
|
+
const { result } = renderHook(() => useFetcher({ fetcher: mockFetcher }));
|
|
1123
|
+
|
|
1124
|
+
act(() => {
|
|
1125
|
+
result.current.execute({ url: '/api/test', method: 'GET' });
|
|
1126
|
+
});
|
|
1127
|
+
|
|
1128
|
+
await waitFor(() => {
|
|
1129
|
+
expect(result.current.loading).toBe(false);
|
|
1130
|
+
expect(result.current.result).toEqual(mockData);
|
|
1131
|
+
expect(result.current.error).toBe(null);
|
|
1132
|
+
});
|
|
1133
|
+
});
|
|
1134
|
+
|
|
1135
|
+
it('should handle fetch error', async () => {
|
|
1136
|
+
const mockError = new Error('Network error');
|
|
1137
|
+
const mockFetcher = { request: jest.fn().mockRejectedValue(mockError) };
|
|
1138
|
+
|
|
1139
|
+
const { result } = renderHook(() => useFetcher({ fetcher: mockFetcher }));
|
|
1140
|
+
|
|
1141
|
+
act(() => {
|
|
1142
|
+
result.current.execute({ url: '/api/test', method: 'GET' });
|
|
1143
|
+
});
|
|
1144
|
+
|
|
1145
|
+
await waitFor(() => {
|
|
1146
|
+
expect(result.current.loading).toBe(false);
|
|
1147
|
+
expect(result.current.error).toEqual(mockError);
|
|
1148
|
+
expect(result.current.result).toBe(null);
|
|
1149
|
+
});
|
|
1150
|
+
});
|
|
1151
|
+
});
|
|
1152
|
+
|
|
1153
|
+
describe('useListQuery', () => {
|
|
1154
|
+
it('should manage query state', async () => {
|
|
1155
|
+
const mockData = [{ id: 1, name: 'Item 1' }];
|
|
1156
|
+
const mockExecute = jest.fn().mockResolvedValue(mockData);
|
|
1157
|
+
|
|
1158
|
+
const { result } = renderHook(() =>
|
|
1159
|
+
useListQuery({
|
|
1160
|
+
initialQuery: { condition: {}, projection: {}, sort: [], limit: 10 },
|
|
1161
|
+
execute: mockExecute,
|
|
1162
|
+
}),
|
|
1163
|
+
);
|
|
1164
|
+
|
|
1165
|
+
act(() => {
|
|
1166
|
+
result.current.execute();
|
|
1167
|
+
});
|
|
1168
|
+
|
|
1169
|
+
await waitFor(() => {
|
|
1170
|
+
expect(result.current.loading).toBe(false);
|
|
1171
|
+
expect(result.current.result).toEqual(mockData);
|
|
1172
|
+
});
|
|
1173
|
+
|
|
1174
|
+
expect(mockExecute).toHaveBeenCalledWith({
|
|
1175
|
+
condition: {},
|
|
1176
|
+
projection: {},
|
|
1177
|
+
sort: [],
|
|
1178
|
+
limit: 10,
|
|
1179
|
+
});
|
|
1180
|
+
});
|
|
1181
|
+
|
|
1182
|
+
it('should update condition', () => {
|
|
1183
|
+
const { result } = renderHook(() =>
|
|
1184
|
+
useListQuery({
|
|
1185
|
+
initialQuery: { condition: {}, projection: {}, sort: [], limit: 10 },
|
|
1186
|
+
execute: jest.fn(),
|
|
1187
|
+
}),
|
|
1188
|
+
);
|
|
1189
|
+
|
|
1190
|
+
act(() => {
|
|
1191
|
+
result.current.setCondition({ status: 'active' });
|
|
1192
|
+
});
|
|
1193
|
+
|
|
1194
|
+
expect(result.current.condition).toEqual({ status: 'active' });
|
|
1195
|
+
});
|
|
1196
|
+
});
|
|
1197
|
+
```
|
|
1198
|
+
|
|
727
1199
|
## API Reference
|
|
728
1200
|
|
|
729
1201
|
### useFetcher
|
|
@@ -745,10 +1217,10 @@ flexible configuration.
|
|
|
745
1217
|
**Parameters:**
|
|
746
1218
|
|
|
747
1219
|
- `options`: Configuration options or supplier function
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
1220
|
+
- `fetcher`: Custom fetcher instance to use. Defaults to the default fetcher.
|
|
1221
|
+
- `initialStatus`: Initial status, defaults to IDLE
|
|
1222
|
+
- `onSuccess`: Callback invoked on success
|
|
1223
|
+
- `onError`: Callback invoked on error
|
|
752
1224
|
|
|
753
1225
|
**Returns:**
|
|
754
1226
|
|
|
@@ -780,9 +1252,9 @@ state options.
|
|
|
780
1252
|
**Parameters:**
|
|
781
1253
|
|
|
782
1254
|
- `options`: Configuration options
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
1255
|
+
- `initialStatus`: Initial status, defaults to IDLE
|
|
1256
|
+
- `onSuccess`: Callback invoked on success
|
|
1257
|
+
- `onError`: Callback invoked on error
|
|
786
1258
|
|
|
787
1259
|
**Returns:**
|
|
788
1260
|
|
|
@@ -814,9 +1286,9 @@ suppliers.
|
|
|
814
1286
|
**Parameters:**
|
|
815
1287
|
|
|
816
1288
|
- `options`: Configuration options or supplier function
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
1289
|
+
- `initialStatus`: Initial status, defaults to IDLE
|
|
1290
|
+
- `onSuccess`: Callback invoked on success (can be async)
|
|
1291
|
+
- `onError`: Callback invoked on error (can be async)
|
|
820
1292
|
|
|
821
1293
|
**Returns:**
|
|
822
1294
|
|
|
@@ -907,7 +1379,7 @@ A React hook for managing list queries with state management for conditions, pro
|
|
|
907
1379
|
**Parameters:**
|
|
908
1380
|
|
|
909
1381
|
- `options`: Configuration options including initialQuery and list function
|
|
910
|
-
|
|
1382
|
+
- `autoExecute`: Whether to automatically execute the query on component mount (defaults to false)
|
|
911
1383
|
|
|
912
1384
|
**Returns:**
|
|
913
1385
|
|
|
@@ -932,7 +1404,7 @@ A React hook for managing paged queries with state management for conditions, pr
|
|
|
932
1404
|
**Parameters:**
|
|
933
1405
|
|
|
934
1406
|
- `options`: Configuration options including initialQuery and query function
|
|
935
|
-
|
|
1407
|
+
- `autoExecute`: Whether to automatically execute the query on component mount (defaults to false)
|
|
936
1408
|
|
|
937
1409
|
**Returns:**
|
|
938
1410
|
|
|
@@ -957,7 +1429,7 @@ A React hook for managing single queries with state management for conditions, p
|
|
|
957
1429
|
**Parameters:**
|
|
958
1430
|
|
|
959
1431
|
- `options`: Configuration options including initialQuery and query function
|
|
960
|
-
|
|
1432
|
+
- `autoExecute`: Whether to automatically execute the query on component mount (defaults to false)
|
|
961
1433
|
|
|
962
1434
|
**Returns:**
|
|
963
1435
|
|
|
@@ -981,7 +1453,7 @@ A React hook for managing count queries with state management for conditions.
|
|
|
981
1453
|
**Parameters:**
|
|
982
1454
|
|
|
983
1455
|
- `options`: Configuration options including initialQuery and execute function
|
|
984
|
-
|
|
1456
|
+
- `autoExecute`: Whether to automatically execute the query on component mount (defaults to false)
|
|
985
1457
|
|
|
986
1458
|
**Returns:**
|
|
987
1459
|
|
|
@@ -1011,7 +1483,7 @@ Returns a readable stream of JSON server-sent events.
|
|
|
1011
1483
|
**Parameters:**
|
|
1012
1484
|
|
|
1013
1485
|
- `options`: Configuration options including initialQuery and listStream function
|
|
1014
|
-
|
|
1486
|
+
- `autoExecute`: Whether to automatically execute the query on component mount (defaults to false)
|
|
1015
1487
|
|
|
1016
1488
|
**Returns:**
|
|
1017
1489
|
|