@umituz/react-native-settings 4.20.58 → 4.20.60
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/.github/ISSUE_TEMPLATE/bug_report.md +51 -0
- package/.github/ISSUE_TEMPLATE/documentation.md +52 -0
- package/.github/ISSUE_TEMPLATE/feature_request.md +63 -0
- package/.github/PULL_REQUEST_TEMPLATE.md +84 -0
- package/AI_AGENT_GUIDELINES.md +367 -0
- package/ARCHITECTURE.md +246 -0
- package/CHANGELOG.md +67 -0
- package/CODE_OF_CONDUCT.md +75 -0
- package/CONTRIBUTING.md +107 -0
- package/DOCUMENTATION_MIGRATION.md +319 -0
- package/DOCUMENTATION_TEMPLATE.md +155 -0
- package/LICENSE +21 -0
- package/README.md +321 -498
- package/SECURITY.md +98 -0
- package/SETTINGS_SCREEN_GUIDE.md +185 -0
- package/TESTING.md +358 -0
- package/package.json +13 -2
- package/src/application/README.md +85 -271
- package/src/domains/about/README.md +85 -440
- package/src/domains/about/presentation/hooks/README.md +93 -348
- package/src/domains/appearance/README.md +95 -584
- package/src/domains/appearance/hooks/README.md +95 -303
- package/src/domains/appearance/infrastructure/services/README.md +83 -397
- package/src/domains/appearance/presentation/components/README.md +95 -489
- package/src/domains/cloud-sync/README.md +73 -439
- package/src/domains/cloud-sync/presentation/components/README.md +95 -493
- package/src/domains/dev/README.md +71 -457
- package/src/domains/disclaimer/README.md +77 -411
- package/src/domains/disclaimer/presentation/components/README.md +95 -392
- package/src/domains/faqs/README.md +86 -574
- package/src/domains/feedback/README.md +79 -553
- package/src/domains/feedback/presentation/hooks/README.md +93 -426
- package/src/domains/legal/README.md +88 -537
- package/src/domains/rating/README.md +73 -440
- package/src/domains/rating/presentation/components/README.md +95 -475
- package/src/domains/video-tutorials/README.md +77 -470
- package/src/domains/video-tutorials/presentation/components/README.md +95 -431
- package/src/infrastructure/README.md +78 -425
- package/src/infrastructure/repositories/README.md +88 -420
- package/src/infrastructure/services/README.md +74 -460
- package/src/presentation/components/README.md +97 -480
- package/src/presentation/components/SettingsErrorBoundary/README.md +48 -436
- package/src/presentation/components/SettingsFooter/README.md +48 -427
- package/src/presentation/components/SettingsItemCard/README.md +152 -391
- package/src/presentation/components/SettingsItemCard/STRATEGY.md +164 -0
- package/src/presentation/components/SettingsSection/README.md +47 -401
- package/src/presentation/hooks/README.md +95 -389
- package/src/presentation/hooks/mutations/README.md +99 -376
- package/src/presentation/hooks/queries/README.md +111 -353
- package/src/presentation/navigation/README.md +70 -502
- package/src/presentation/navigation/SettingsStackNavigator.tsx +2 -0
- package/src/presentation/navigation/components/README.md +70 -295
- package/src/presentation/navigation/components/wrappers/SettingsScreenWrapper.tsx +3 -0
- package/src/presentation/navigation/hooks/README.md +75 -367
- package/src/presentation/navigation/types.ts +1 -0
- package/src/presentation/navigation/utils/README.md +100 -380
- package/src/presentation/screens/README.md +53 -504
- package/src/presentation/screens/SettingsScreen.tsx +4 -2
- package/src/presentation/screens/components/SettingsContent/README.md +53 -382
- package/src/presentation/screens/components/SettingsHeader/README.md +48 -303
- package/src/presentation/screens/components/sections/CustomSettingsList/README.md +47 -359
- package/src/presentation/screens/components/sections/FeatureSettingsSection/README.md +81 -176
- package/src/presentation/screens/components/sections/IdentitySettingsSection/README.md +40 -297
- package/src/presentation/screens/components/sections/ProfileSectionLoader/README.md +47 -451
- package/src/presentation/screens/components/sections/SupportSettingsSection/README.md +45 -361
- package/src/presentation/screens/hooks/README.md +64 -354
- package/src/presentation/screens/types/README.md +79 -409
- package/src/presentation/screens/utils/README.md +65 -255
|
@@ -2,423 +2,187 @@
|
|
|
2
2
|
|
|
3
3
|
Custom TanStack Query hooks for fetching user settings in the settings system.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Purpose
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Provides React hooks for querying (fetching) user settings with automatic caching, background updates, and loading states. These hooks wrap TanStack Query's useQuery hook with settings-specific functionality.
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
## File Paths
|
|
10
10
|
|
|
11
|
-
```
|
|
12
|
-
|
|
11
|
+
```
|
|
12
|
+
src/presentation/hooks/queries/
|
|
13
|
+
├── useSettingsQuery.ts # Fetch user settings
|
|
14
|
+
└── useSettingsSuspenseQuery.ts # Suspense version
|
|
15
|
+
```
|
|
13
16
|
|
|
14
|
-
|
|
15
|
-
const { data, isLoading, isError, error } = useSettingsQuery('user123');
|
|
17
|
+
## Strategy
|
|
16
18
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
+
1. **Automatic Caching**: Cache query results to reduce network requests
|
|
20
|
+
2. **Background Refetch**: Refresh data in background when it becomes stale
|
|
21
|
+
3. **Loading States**: Provide built-in loading and error indicators
|
|
22
|
+
4. **Conditional Queries**: Enable/disable queries based on conditions
|
|
23
|
+
5. **Type Safety**: Strongly typed query results and parameters
|
|
19
24
|
|
|
20
|
-
|
|
21
|
-
<View>
|
|
22
|
-
<Text>Theme: {data?.settings.theme}</Text>
|
|
23
|
-
<Text>Language: {data?.settings.language}</Text>
|
|
24
|
-
</View>
|
|
25
|
-
);
|
|
26
|
-
}
|
|
27
|
-
```
|
|
25
|
+
## Restrictions
|
|
28
26
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
```typescript
|
|
32
|
-
interface UseSettingsQueryResult {
|
|
33
|
-
data: SettingsResult | undefined;
|
|
34
|
-
isLoading: boolean;
|
|
35
|
-
isError: boolean;
|
|
36
|
-
error: Error | null;
|
|
37
|
-
isFetching: boolean;
|
|
38
|
-
refetch: () => void;
|
|
39
|
-
}
|
|
40
|
-
```
|
|
27
|
+
### DO NOT
|
|
41
28
|
|
|
42
|
-
|
|
29
|
+
- ❌ DO NOT use queries for mutations/updates; use mutations instead
|
|
30
|
+
- ❌ DO NOT call queries outside React components or custom hooks
|
|
31
|
+
- ❌ DO NOT ignore loading and error states
|
|
32
|
+
- ❌ DO NOT use queries for one-time operations; use direct function calls
|
|
33
|
+
- ❌ DO NOT fire queries without proper error boundaries
|
|
43
34
|
|
|
44
|
-
|
|
45
|
-
|-----------|------|----------|-------------|
|
|
46
|
-
| `userId` | `string` | Yes | Unique user identifier |
|
|
47
|
-
| `options` | `UseQueryOptions` | No | TanStack Query options |
|
|
35
|
+
### NEVER
|
|
48
36
|
|
|
49
|
-
|
|
37
|
+
- ❌ NEVER assume query data is always available; check for undefined
|
|
38
|
+
- ❌ NEVER use the same query key for different data
|
|
39
|
+
- ❌ EVER fire queries in render without proper dependencies
|
|
40
|
+
- ❌ EVER use queries for non-idempotent operations
|
|
50
41
|
|
|
51
|
-
|
|
42
|
+
### AVOID
|
|
52
43
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
44
|
+
- ❌ AVOID over-fetching data; request only what's needed
|
|
45
|
+
- ❌ AVOID very short stale times that cause excessive refetching
|
|
46
|
+
- ❌ AVOID firing queries that won't be used (use enabled option)
|
|
47
|
+
- ❌ AVOID ignoring query performance metrics
|
|
56
48
|
|
|
57
|
-
|
|
49
|
+
## Rules
|
|
58
50
|
|
|
59
|
-
|
|
60
|
-
const { data } = useSettingsQuery('user123', {
|
|
61
|
-
staleTime: 5 * 60 * 1000, // 5 minutes
|
|
62
|
-
cacheTime: 10 * 60 * 1000, // 10 minutes
|
|
63
|
-
refetchOnWindowFocus: false,
|
|
64
|
-
refetchOnMount: false,
|
|
65
|
-
});
|
|
66
|
-
```
|
|
51
|
+
### ALWAYS
|
|
67
52
|
|
|
68
|
-
|
|
53
|
+
- ✅ ALWAYS handle loading and error states
|
|
54
|
+
- ✅ ALWAYS provide meaningful query keys for cache management
|
|
55
|
+
- ✅ ALWAYS use appropriate staleTime and cacheTime values
|
|
56
|
+
- ✅ ALWAYS check if data exists before accessing it
|
|
57
|
+
- ✅ ALWAYS use enabled option for conditional queries
|
|
69
58
|
|
|
70
|
-
|
|
71
|
-
const { data, refetch } = useSettingsQuery('user123');
|
|
59
|
+
### MUST
|
|
72
60
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
61
|
+
- ✅ MUST wrap queries in React components or custom hooks
|
|
62
|
+
- ✅ MUST provide error boundaries for queries
|
|
63
|
+
- ✅ MUST handle undefined data states
|
|
64
|
+
- ✅ MUST use consistent query key patterns
|
|
76
65
|
|
|
77
|
-
|
|
78
|
-
<PullToRefresh onRefresh={handleRefresh}>
|
|
79
|
-
<SettingsContent settings={data?.settings} />
|
|
80
|
-
</PullToRefresh>
|
|
81
|
-
);
|
|
82
|
-
```
|
|
66
|
+
### SHOULD
|
|
83
67
|
|
|
84
|
-
|
|
68
|
+
- ✅ SHOULD use suspense queries for cleaner code when possible
|
|
69
|
+
- ✅ SHOULD prefetch data for expected navigation
|
|
70
|
+
- ✅ SHOULD configure refetch behavior appropriately
|
|
71
|
+
- ✅ SHOULD use query selectors for derived data
|
|
85
72
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
73
|
+
## AI Agent Guidelines
|
|
74
|
+
|
|
75
|
+
1. **When creating queries**: Always define clear query key patterns and result types
|
|
76
|
+
2. **When setting cache times**: Balance freshness with performance
|
|
77
|
+
3. **When using conditional queries**: Use the enabled option with proper conditions
|
|
78
|
+
4. **When handling errors**: Provide user-friendly error messages and retry options
|
|
79
|
+
5. **When adding new queries**: Follow existing query patterns for consistency
|
|
80
|
+
|
|
81
|
+
## Queries Reference
|
|
82
|
+
|
|
83
|
+
### useSettingsQuery
|
|
84
|
+
|
|
85
|
+
Hook for fetching user settings with caching and automatic refetching.
|
|
86
|
+
|
|
87
|
+
**Location**: `/Users/umituz/Desktop/github/umituz/apps/artificial_intelligence/npm-packages/react-native-settings/src/presentation/hooks/queries/useSettingsQuery.ts`
|
|
88
|
+
|
|
89
|
+
**Parameters**: `userId: string, options?: UseQueryOptions`
|
|
90
|
+
**Returns**: `UseSettingsQueryResult` with data, isLoading, isError, error, isFetching, refetch
|
|
91
|
+
|
|
92
|
+
**Use Cases**:
|
|
93
|
+
- Loading user settings on component mount
|
|
94
|
+
- Displaying current settings
|
|
95
|
+
- Refreshing settings after updates
|
|
92
96
|
|
|
93
97
|
### useSettingsSuspenseQuery
|
|
94
98
|
|
|
95
99
|
Suspense version of settings query for React Suspense boundaries.
|
|
96
100
|
|
|
97
|
-
|
|
98
|
-
import { useSettingsSuspenseQuery } from '@umituz/react-native-settings';
|
|
99
|
-
|
|
100
|
-
function SettingsScreen() {
|
|
101
|
-
const { data } = useSettingsSuspenseQuery('user123');
|
|
102
|
-
|
|
103
|
-
// Data is guaranteed to be available
|
|
104
|
-
return (
|
|
105
|
-
<View>
|
|
106
|
-
<Text>Theme: {data.settings.theme}</Text>
|
|
107
|
-
</View>
|
|
108
|
-
);
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
// Wrap in Suspense boundary
|
|
112
|
-
function App() {
|
|
113
|
-
return (
|
|
114
|
-
<Suspense fallback={<LoadingSpinner />}>
|
|
115
|
-
<SettingsScreen />
|
|
116
|
-
</Suspense>
|
|
117
|
-
);
|
|
118
|
-
}
|
|
119
|
-
```
|
|
101
|
+
**Location**: `/Users/umituz/Desktop/github/umituz/apps/artificial_intelligence/npm-packages/react-native-settings/src/presentation/hooks/queries/useSettingsSuspenseQuery.ts`
|
|
120
102
|
|
|
121
|
-
|
|
103
|
+
**Parameters**: `userId: string, options?: UseQueryOptions`
|
|
104
|
+
**Returns**: `UseSettingsSuspenseQueryResult` with guaranteed data availability
|
|
122
105
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
```
|
|
106
|
+
**Use Cases**:
|
|
107
|
+
- Clean code with Suspense boundaries
|
|
108
|
+
- Simplified loading states
|
|
109
|
+
- Route-level data fetching
|
|
128
110
|
|
|
129
111
|
## Query Options
|
|
130
112
|
|
|
131
113
|
### staleTime
|
|
132
114
|
|
|
133
|
-
Time in milliseconds after which data is considered stale.
|
|
115
|
+
Time in milliseconds after which data is considered stale. Higher values reduce refetching but may show outdated data.
|
|
134
116
|
|
|
135
|
-
|
|
136
|
-
const { data } = useSettingsQuery('user123', {
|
|
137
|
-
staleTime: 5 * 60 * 1000, // 5 minutes
|
|
138
|
-
});
|
|
139
|
-
```
|
|
117
|
+
**Recommended**: 5-15 minutes for user settings
|
|
140
118
|
|
|
141
119
|
### cacheTime
|
|
142
120
|
|
|
143
|
-
Time in milliseconds that unused data remains in cache.
|
|
121
|
+
Time in milliseconds that unused data remains in cache. Higher values use more memory but improve performance.
|
|
144
122
|
|
|
145
|
-
|
|
146
|
-
const { data } = useSettingsQuery('user123', {
|
|
147
|
-
cacheTime: 10 * 60 * 1000, // 10 minutes
|
|
148
|
-
});
|
|
149
|
-
```
|
|
123
|
+
**Recommended**: 10-30 minutes for settings
|
|
150
124
|
|
|
151
125
|
### refetchOnWindowFocus
|
|
152
126
|
|
|
153
|
-
Refetch query when window regains focus.
|
|
127
|
+
Refetch query when window regains focus. Useful for keeping data fresh but may cause unnecessary refetches.
|
|
154
128
|
|
|
155
|
-
|
|
156
|
-
const { data } = useSettingsQuery('user123', {
|
|
157
|
-
refetchOnWindowFocus: true, // Default: true
|
|
158
|
-
});
|
|
159
|
-
```
|
|
129
|
+
**Recommended**: `false` for settings (rarely changes from external sources)
|
|
160
130
|
|
|
161
131
|
### refetchOnMount
|
|
162
132
|
|
|
163
|
-
Refetch query on component mount.
|
|
133
|
+
Refetch query on component mount. Ensures fresh data but may delay initial render.
|
|
164
134
|
|
|
165
|
-
|
|
166
|
-
const { data } = useSettingsQuery('user123', {
|
|
167
|
-
refetchOnMount: true, // Default: true
|
|
168
|
-
});
|
|
169
|
-
```
|
|
135
|
+
**Recommended**: `false` if data is cached and fresh
|
|
170
136
|
|
|
171
137
|
### refetchOnReconnect
|
|
172
138
|
|
|
173
|
-
Refetch query when network reconnects.
|
|
139
|
+
Refetch query when network reconnects. Useful for offline scenarios.
|
|
174
140
|
|
|
175
|
-
|
|
176
|
-
const { data } = useSettingsQuery('user123', {
|
|
177
|
-
refetchOnReconnect: true, // Default: true
|
|
178
|
-
});
|
|
179
|
-
```
|
|
141
|
+
**Recommended**: `true` for better offline support
|
|
180
142
|
|
|
181
143
|
### enabled
|
|
182
144
|
|
|
183
|
-
Conditionally enable/disable query.
|
|
145
|
+
Conditionally enable/disable query execution.
|
|
184
146
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
```
|
|
147
|
+
**Use Cases**:
|
|
148
|
+
- Wait for userId to be available
|
|
149
|
+
- Check authentication status
|
|
150
|
+
- Implement feature flags
|
|
190
151
|
|
|
191
152
|
### onSuccess
|
|
192
153
|
|
|
193
|
-
Callback executed on successful query.
|
|
154
|
+
Callback executed on successful query completion.
|
|
194
155
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
Analytics.track('settings_loaded', { theme: data.settings.theme });
|
|
200
|
-
},
|
|
201
|
-
});
|
|
202
|
-
```
|
|
156
|
+
**Use Cases**:
|
|
157
|
+
- Analytics tracking
|
|
158
|
+
- Logging data fetches
|
|
159
|
+
- Triggering side effects
|
|
203
160
|
|
|
204
161
|
### onError
|
|
205
162
|
|
|
206
163
|
Callback executed on query error.
|
|
207
164
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
Alert.alert('Error', 'Could not load settings');
|
|
213
|
-
},
|
|
214
|
-
});
|
|
215
|
-
```
|
|
165
|
+
**Use Cases**:
|
|
166
|
+
- Error logging
|
|
167
|
+
- User notifications
|
|
168
|
+
- Fallback logic
|
|
216
169
|
|
|
217
170
|
### onSettled
|
|
218
171
|
|
|
219
172
|
Callback executed after query succeeds or fails.
|
|
220
173
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
Analytics.track('settings_load_failed');
|
|
226
|
-
} else {
|
|
227
|
-
Analytics.track('settings_load_success');
|
|
228
|
-
}
|
|
229
|
-
},
|
|
230
|
-
});
|
|
231
|
-
```
|
|
232
|
-
|
|
233
|
-
## Usage Examples
|
|
234
|
-
|
|
235
|
-
### Complete Loading States
|
|
236
|
-
|
|
237
|
-
```tsx
|
|
238
|
-
function SettingsScreen() {
|
|
239
|
-
const { data, isLoading, isError, error } = useSettingsQuery('user123');
|
|
240
|
-
|
|
241
|
-
if (isLoading) {
|
|
242
|
-
return (
|
|
243
|
-
<View style={styles.centered}>
|
|
244
|
-
<ActivityIndicator size="large" />
|
|
245
|
-
<Text>Loading settings...</Text>
|
|
246
|
-
</View>
|
|
247
|
-
);
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
if (isError) {
|
|
251
|
-
return (
|
|
252
|
-
<View style={styles.centered}>
|
|
253
|
-
<Text style={styles.error}>Error: {error.message}</Text>
|
|
254
|
-
<Button title="Retry" onPress={() => refetch()} />
|
|
255
|
-
</View>
|
|
256
|
-
);
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
return (
|
|
260
|
-
<SettingsContent settings={data?.settings} />
|
|
261
|
-
);
|
|
262
|
-
}
|
|
263
|
-
```
|
|
264
|
-
|
|
265
|
-
### Pull to Refresh
|
|
266
|
-
|
|
267
|
-
```tsx
|
|
268
|
-
function SettingsScreen() {
|
|
269
|
-
const { data, refetch, isFetching } = useSettingsQuery('user123');
|
|
270
|
-
|
|
271
|
-
return (
|
|
272
|
-
<ScrollView
|
|
273
|
-
refreshControl={
|
|
274
|
-
<RefreshControl
|
|
275
|
-
refreshing={isFetching}
|
|
276
|
-
onRefresh={() => refetch()}
|
|
277
|
-
/>
|
|
278
|
-
}
|
|
279
|
-
>
|
|
280
|
-
<SettingsContent settings={data?.settings} />
|
|
281
|
-
</ScrollView>
|
|
282
|
-
);
|
|
283
|
-
}
|
|
284
|
-
```
|
|
285
|
-
|
|
286
|
-
### Background Refetch
|
|
287
|
-
|
|
288
|
-
```tsx
|
|
289
|
-
function SettingsScreen() {
|
|
290
|
-
const { data } = useSettingsQuery('user123', {
|
|
291
|
-
refetchInterval: 60000, // Refetch every minute
|
|
292
|
-
refetchIntervalInBackground: true,
|
|
293
|
-
});
|
|
294
|
-
|
|
295
|
-
return <SettingsContent settings={data?.settings} />;
|
|
296
|
-
}
|
|
297
|
-
```
|
|
298
|
-
|
|
299
|
-
### Conditional Query
|
|
300
|
-
|
|
301
|
-
```tsx
|
|
302
|
-
function SettingsScreen({ userId, enabled }) {
|
|
303
|
-
const { data } = useSettingsQuery(userId, {
|
|
304
|
-
enabled: enabled && !!userId,
|
|
305
|
-
});
|
|
306
|
-
|
|
307
|
-
if (!enabled) {
|
|
308
|
-
return <Text>Please log in to view settings</Text>;
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
return <SettingsContent settings={data?.settings} />;
|
|
312
|
-
}
|
|
313
|
-
```
|
|
314
|
-
|
|
315
|
-
### Query Invalidation
|
|
316
|
-
|
|
317
|
-
```tsx
|
|
318
|
-
function SettingsUpdater() {
|
|
319
|
-
const queryClient = useQueryClient();
|
|
320
|
-
const updateSettings = useUpdateSettingsMutation();
|
|
321
|
-
|
|
322
|
-
const handleUpdate = (newSettings) => {
|
|
323
|
-
updateSettings.mutate(
|
|
324
|
-
{ userId: 'user123', settings: newSettings },
|
|
325
|
-
{
|
|
326
|
-
onSuccess: () => {
|
|
327
|
-
// Invalidate and refetch
|
|
328
|
-
queryClient.invalidateQueries(['settings', 'user123']);
|
|
329
|
-
},
|
|
330
|
-
}
|
|
331
|
-
);
|
|
332
|
-
};
|
|
333
|
-
|
|
334
|
-
return <Button onPress={handleUpdate} title="Update" />;
|
|
335
|
-
}
|
|
336
|
-
```
|
|
337
|
-
|
|
338
|
-
### Optimistic Updates with Query
|
|
339
|
-
|
|
340
|
-
```tsx
|
|
341
|
-
function SettingsScreen() {
|
|
342
|
-
const queryClient = useQueryClient();
|
|
343
|
-
const { data } = useSettingsQuery('user123');
|
|
344
|
-
|
|
345
|
-
const handleThemeChange = (newTheme) => {
|
|
346
|
-
// Optimistically update
|
|
347
|
-
queryClient.setQueryData(['settings', 'user123'], (old: any) => ({
|
|
348
|
-
...old,
|
|
349
|
-
settings: {
|
|
350
|
-
...old.settings,
|
|
351
|
-
theme: newTheme,
|
|
352
|
-
},
|
|
353
|
-
}));
|
|
354
|
-
|
|
355
|
-
// Then update on server
|
|
356
|
-
updateSettings.mutate({
|
|
357
|
-
userId: 'user123',
|
|
358
|
-
settings: { theme: newTheme },
|
|
359
|
-
});
|
|
360
|
-
};
|
|
361
|
-
|
|
362
|
-
return (
|
|
363
|
-
<ThemeSelector
|
|
364
|
-
value={data?.settings.theme}
|
|
365
|
-
onChange={handleThemeChange}
|
|
366
|
-
/>
|
|
367
|
-
);
|
|
368
|
-
}
|
|
369
|
-
```
|
|
174
|
+
**Use Cases**:
|
|
175
|
+
- Hide loading indicators
|
|
176
|
+
- Clean up resources
|
|
177
|
+
- Update UI state
|
|
370
178
|
|
|
371
179
|
## Query Keys
|
|
372
180
|
|
|
373
|
-
|
|
181
|
+
Consistent query key patterns for cache management:
|
|
374
182
|
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
['settings', userId]
|
|
378
|
-
|
|
379
|
-
// All settings (admin)
|
|
380
|
-
['settings']
|
|
381
|
-
|
|
382
|
-
// Settings with filters
|
|
383
|
-
['settings', userId, { type: 'appearance' }]
|
|
384
|
-
|
|
385
|
-
// Infinite settings (pagination)
|
|
386
|
-
['settings', 'infinite']
|
|
387
|
-
```
|
|
388
|
-
|
|
389
|
-
### Manual Invalidation
|
|
390
|
-
|
|
391
|
-
```tsx
|
|
392
|
-
// Invalidate specific user
|
|
393
|
-
queryClient.invalidateQueries(['settings', 'user123']);
|
|
394
|
-
|
|
395
|
-
// Invalidate all settings
|
|
396
|
-
queryClient.invalidateQueries(['settings']);
|
|
397
|
-
|
|
398
|
-
// Remove from cache
|
|
399
|
-
queryClient.removeQueries(['settings', 'user123']);
|
|
400
|
-
|
|
401
|
-
// Reset cache
|
|
402
|
-
queryClient.resetQueries(['settings']);
|
|
403
|
-
```
|
|
404
|
-
|
|
405
|
-
### Prefetching
|
|
406
|
-
|
|
407
|
-
```tsx
|
|
408
|
-
// Prefetch settings for expected navigation
|
|
409
|
-
const prefetchSettings = async (userId: string) => {
|
|
410
|
-
await queryClient.prefetchQuery(['settings', userId], () =>
|
|
411
|
-
fetchSettings(userId)
|
|
412
|
-
);
|
|
413
|
-
};
|
|
414
|
-
|
|
415
|
-
// Usage
|
|
416
|
-
useEffect(() => {
|
|
417
|
-
if (likelyToNavigate) {
|
|
418
|
-
prefetchSettings('user123');
|
|
419
|
-
}
|
|
420
|
-
}, [likelyToNavigate]);
|
|
421
|
-
```
|
|
183
|
+
**Single user settings**: `['settings', userId]`
|
|
184
|
+
**All settings (admin)**: `['settings']`
|
|
185
|
+
**Settings with filters**: `['settings', userId, { type: 'appearance' }]`
|
|
422
186
|
|
|
423
187
|
## Best Practices
|
|
424
188
|
|
|
@@ -428,13 +192,7 @@ useEffect(() => {
|
|
|
428
192
|
4. **Query Keys**: Use consistent query keys for cache management
|
|
429
193
|
5. **Prefetching**: Prefetch data for smooth navigation
|
|
430
194
|
6. **Optimistic Updates**: Combine with mutations for instant feedback
|
|
431
|
-
7. **Suspense**: Use suspense queries for cleaner code
|
|
432
|
-
|
|
433
|
-
## Related
|
|
434
|
-
|
|
435
|
-
- **Settings Mutations**: Mutation hooks for updating settings
|
|
436
|
-
- **useSettings**: Combined hook for settings management
|
|
437
|
-
- **TanStack Query**: Official Query documentation
|
|
195
|
+
7. **Suspense**: Use suspense queries for cleaner code when possible
|
|
438
196
|
|
|
439
197
|
## License
|
|
440
198
|
|