@umituz/react-native-settings 4.20.57 → 4.20.59
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/__tests__/setup.ts +1 -4
- 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 +99 -0
- 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 -442
- package/src/presentation/components/SettingsFooter/README.md +48 -427
- package/src/presentation/components/SettingsItemCard/README.md +153 -392
- 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/components/README.md +70 -295
- package/src/presentation/navigation/hooks/README.md +75 -367
- package/src/presentation/navigation/utils/README.md +100 -380
- package/src/presentation/screens/README.md +53 -504
- 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,428 +2,151 @@
|
|
|
2
2
|
|
|
3
3
|
Custom TanStack Query mutations for updating user settings in the settings system.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Purpose
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Provides React hooks for mutating (updating) user settings with automatic loading states, error handling, and cache invalidation. These hooks wrap TanStack Query's useMutation hook with settings-specific functionality.
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
```tsx
|
|
12
|
-
import { useUpdateSettingsMutation } from '@umituz/react-native-settings';
|
|
13
|
-
|
|
14
|
-
function SettingsScreen() {
|
|
15
|
-
const updateSettings = useUpdateSettingsMutation();
|
|
16
|
-
|
|
17
|
-
const handleThemeChange = useCallback((theme: 'light' | 'dark') => {
|
|
18
|
-
updateSettings.mutate(
|
|
19
|
-
{ userId: 'user123', settings: { theme } },
|
|
20
|
-
{
|
|
21
|
-
onSuccess: () => {
|
|
22
|
-
console.log('Settings updated successfully');
|
|
23
|
-
},
|
|
24
|
-
onError: (error) => {
|
|
25
|
-
console.error('Failed to update settings:', error);
|
|
26
|
-
},
|
|
27
|
-
}
|
|
28
|
-
);
|
|
29
|
-
}, [updateSettings]);
|
|
30
|
-
|
|
31
|
-
return <ThemeSelector onThemeChange={handleThemeChange} />;
|
|
32
|
-
}
|
|
33
|
-
```
|
|
9
|
+
## File Paths
|
|
34
10
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
mutate: (variables: UpdateSettingsVariables) => void;
|
|
40
|
-
mutateAsync: (variables: UpdateSettingsVariables) => Promise<SettingsResult>;
|
|
41
|
-
isLoading: boolean;
|
|
42
|
-
isError: boolean;
|
|
43
|
-
error: Error | null;
|
|
44
|
-
data: SettingsResult | undefined;
|
|
45
|
-
reset: () => void;
|
|
46
|
-
}
|
|
11
|
+
```
|
|
12
|
+
src/presentation/hooks/mutations/
|
|
13
|
+
├── useUpdateSettingsMutation.ts # Update user settings
|
|
14
|
+
└── useResetSettingsMutation.ts # Reset to defaults
|
|
47
15
|
```
|
|
48
16
|
|
|
49
|
-
|
|
17
|
+
## Strategy
|
|
50
18
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
```
|
|
19
|
+
1. **Optimistic Updates**: Update UI immediately before server confirmation for better UX
|
|
20
|
+
2. **Automatic Invalidation**: Invalidate related queries after mutations complete
|
|
21
|
+
3. **Error Rollback**: Rollback optimistic updates on error
|
|
22
|
+
4. **Loading States**: Provide built-in loading indicators
|
|
23
|
+
5. **Type Safety**: Strongly typed mutation variables and results
|
|
57
24
|
|
|
58
|
-
|
|
25
|
+
## Restrictions
|
|
59
26
|
|
|
60
|
-
|
|
27
|
+
### DO NOT
|
|
61
28
|
|
|
62
|
-
|
|
63
|
-
|
|
29
|
+
- ❌ DO NOT use mutations for fetching data; use queries instead
|
|
30
|
+
- ❌ DO NOT call mutations outside event handlers or callbacks
|
|
31
|
+
- ❌ DO NOT assume mutations will always succeed
|
|
32
|
+
- ❌ DO NOT forget to handle error states
|
|
33
|
+
- ❌ DO NOT use multiple mutations for the same data without coordination
|
|
64
34
|
|
|
65
|
-
|
|
66
|
-
updateSettings.mutate({
|
|
67
|
-
userId: 'user123',
|
|
68
|
-
settings: { notificationsEnabled: !settings.notificationsEnabled },
|
|
69
|
-
});
|
|
70
|
-
};
|
|
71
|
-
```
|
|
35
|
+
### NEVER
|
|
72
36
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
const updateMultipleSettings = () => {
|
|
79
|
-
updateSettings.mutate({
|
|
80
|
-
userId: 'user123',
|
|
81
|
-
settings: {
|
|
82
|
-
theme: 'dark',
|
|
83
|
-
language: 'tr-TR',
|
|
84
|
-
notificationsEnabled: true,
|
|
85
|
-
},
|
|
86
|
-
});
|
|
87
|
-
};
|
|
88
|
-
```
|
|
37
|
+
- ❌ NEVER call mutate functions in render; use event handlers
|
|
38
|
+
- ❌ NEVER ignore the isLoading state during mutations
|
|
39
|
+
- ❌ NEVER fire mutations without proper user intent (e.g., in useEffect)
|
|
40
|
+
- ❌ EVER use mutations for data transformation; use the service layer
|
|
89
41
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
```tsx
|
|
93
|
-
const updateSettings = useUpdateSettingsMutation();
|
|
94
|
-
|
|
95
|
-
const handleOptimisticUpdate = (newTheme: 'light' | 'dark') => {
|
|
96
|
-
updateSettings.mutate(
|
|
97
|
-
{ userId: 'user123', settings: { theme: newTheme } },
|
|
98
|
-
{
|
|
99
|
-
onMutate: async (newData) => {
|
|
100
|
-
// Cancel ongoing queries
|
|
101
|
-
await queryClient.cancelQueries(['settings', newData.userId]);
|
|
102
|
-
|
|
103
|
-
// Snapshot previous value
|
|
104
|
-
const previousSettings = queryClient.getQueryData(['settings', newData.userId]);
|
|
105
|
-
|
|
106
|
-
// Optimistically update
|
|
107
|
-
queryClient.setQueryData(['settings', newData.userId], (old: any) => ({
|
|
108
|
-
...old,
|
|
109
|
-
...newData.settings,
|
|
110
|
-
}));
|
|
111
|
-
|
|
112
|
-
// Return context for rollback
|
|
113
|
-
return { previousSettings };
|
|
114
|
-
},
|
|
115
|
-
onError: (err, newData, context) => {
|
|
116
|
-
// Rollback on error
|
|
117
|
-
queryClient.setQueryData(['settings', newData.userId], context?.previousSettings);
|
|
118
|
-
},
|
|
119
|
-
onSettled: (data, error, newData) => {
|
|
120
|
-
// Refetch on success or error
|
|
121
|
-
queryClient.invalidateQueries(['settings', newData.userId]);
|
|
122
|
-
},
|
|
123
|
-
}
|
|
124
|
-
);
|
|
125
|
-
};
|
|
126
|
-
```
|
|
42
|
+
### AVOID
|
|
127
43
|
|
|
128
|
-
|
|
44
|
+
- ❌ AVOID firing mutations too frequently (debounce when needed)
|
|
45
|
+
- ❌ AVOID complex mutation logic in components; extract to custom hooks
|
|
46
|
+
- ❌ AVOID silent failures; always provide user feedback
|
|
47
|
+
- ❌ AVOID mutations that take too long without progress indication
|
|
129
48
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
```tsx
|
|
133
|
-
import { useResetSettingsMutation } from '@umituz/react-native-settings';
|
|
134
|
-
|
|
135
|
-
function SettingsScreen() {
|
|
136
|
-
const resetSettings = useResetSettingsMutation();
|
|
137
|
-
|
|
138
|
-
const handleReset = useCallback(() => {
|
|
139
|
-
Alert.alert(
|
|
140
|
-
'Reset Settings',
|
|
141
|
-
'Are you sure you want to reset all settings to default?',
|
|
142
|
-
[
|
|
143
|
-
{ text: 'Cancel', style: 'cancel' },
|
|
144
|
-
{
|
|
145
|
-
text: 'Reset',
|
|
146
|
-
style: 'destructive',
|
|
147
|
-
onPress: () => {
|
|
148
|
-
resetSettings.mutate('user123', {
|
|
149
|
-
onSuccess: () => {
|
|
150
|
-
Alert.alert('Success', 'Settings have been reset');
|
|
151
|
-
},
|
|
152
|
-
});
|
|
153
|
-
},
|
|
154
|
-
},
|
|
155
|
-
]
|
|
156
|
-
);
|
|
157
|
-
}, [resetSettings]);
|
|
158
|
-
|
|
159
|
-
return <Button onPress={handleReset} title="Reset Settings" />;
|
|
160
|
-
}
|
|
161
|
-
```
|
|
49
|
+
## Rules
|
|
162
50
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
```typescript
|
|
166
|
-
interface ResetSettingsMutationResult {
|
|
167
|
-
mutate: (variables: string) => void;
|
|
168
|
-
mutateAsync: (variables: string) => Promise<SettingsResult>;
|
|
169
|
-
isLoading: boolean;
|
|
170
|
-
isError: boolean;
|
|
171
|
-
error: Error | null;
|
|
172
|
-
data: SettingsResult | undefined;
|
|
173
|
-
reset: () => void;
|
|
174
|
-
}
|
|
175
|
-
```
|
|
51
|
+
### ALWAYS
|
|
176
52
|
|
|
177
|
-
|
|
53
|
+
- ✅ ALWAYS handle loading states during mutations
|
|
54
|
+
- ✅ ALWAYS provide user feedback for success/error
|
|
55
|
+
- ✅ ALWAYS invalidate related queries after mutations
|
|
56
|
+
- ✅ ALWAYS implement rollback for optimistic updates
|
|
57
|
+
- ✅ ALWAYS use mutation variables to pass data
|
|
178
58
|
|
|
179
|
-
|
|
59
|
+
### MUST
|
|
180
60
|
|
|
181
|
-
|
|
182
|
-
|
|
61
|
+
- ✅ MUST wrap mutations in event handlers (onClick, onSubmit, etc.)
|
|
62
|
+
- ✅ MUST handle errors gracefully with user-friendly messages
|
|
63
|
+
- ✅ MUST confirm destructive operations (reset, delete)
|
|
64
|
+
- ✅ MUST check success status before accessing result data
|
|
183
65
|
|
|
184
|
-
|
|
185
|
-
resetSettings.mutate('user123');
|
|
186
|
-
};
|
|
187
|
-
```
|
|
66
|
+
### SHOULD
|
|
188
67
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
const handleReset = () => {
|
|
195
|
-
Alert.alert(
|
|
196
|
-
'Confirm Reset',
|
|
197
|
-
'This will reset all settings to default. Continue?',
|
|
198
|
-
[
|
|
199
|
-
{ text: 'Cancel', style: 'cancel' },
|
|
200
|
-
{
|
|
201
|
-
text: 'Reset',
|
|
202
|
-
style: 'destructive',
|
|
203
|
-
onPress: () => resetSettings.mutate('user123'),
|
|
204
|
-
},
|
|
205
|
-
]
|
|
206
|
-
);
|
|
207
|
-
};
|
|
208
|
-
```
|
|
68
|
+
- ✅ SHOULD use optimistic updates for instant feedback
|
|
69
|
+
- ✅ SHOULD debounce rapid successive mutations
|
|
70
|
+
- ✅ SHOULD show progress indicators for long-running operations
|
|
71
|
+
- ✅ SHOULD provide retry functionality on failure
|
|
209
72
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
```tsx
|
|
213
|
-
const resetSettings = useResetSettingsMutation();
|
|
214
|
-
|
|
215
|
-
const handleReset = () => {
|
|
216
|
-
resetSettings.mutate('user123', {
|
|
217
|
-
onSuccess: (data) => {
|
|
218
|
-
// Apply default theme
|
|
219
|
-
applyTheme(data.settings.theme);
|
|
220
|
-
|
|
221
|
-
// Restart app if needed
|
|
222
|
-
if (needsRestart) {
|
|
223
|
-
Updates.reloadAsync();
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
Alert.alert('Success', 'Settings reset successfully');
|
|
227
|
-
},
|
|
228
|
-
onError: (error) => {
|
|
229
|
-
Alert.alert('Error', 'Failed to reset settings');
|
|
230
|
-
},
|
|
231
|
-
});
|
|
232
|
-
};
|
|
233
|
-
```
|
|
73
|
+
## AI Agent Guidelines
|
|
234
74
|
|
|
235
|
-
|
|
75
|
+
1. **When creating mutations**: Always define clear variable types and return types
|
|
76
|
+
2. **When using optimistic updates**: Always provide rollback logic in onError
|
|
77
|
+
3. **When invalidating queries**: Invalidate all affected queries after mutations
|
|
78
|
+
4. **When handling errors**: Provide actionable error messages to users
|
|
79
|
+
5. **When adding new mutations**: Follow the pattern of existing mutations for consistency
|
|
236
80
|
|
|
237
|
-
|
|
81
|
+
## Mutations Reference
|
|
238
82
|
|
|
239
|
-
|
|
83
|
+
### useUpdateSettingsMutation
|
|
240
84
|
|
|
241
|
-
|
|
242
|
-
const updateSettings = useUpdateSettingsMutation();
|
|
85
|
+
Hook for updating user settings with partial updates support.
|
|
243
86
|
|
|
244
|
-
|
|
245
|
-
{ userId: 'user123', settings: { theme: 'dark' } },
|
|
246
|
-
{
|
|
247
|
-
onSuccess: (data, variables) => {
|
|
248
|
-
console.log('Updated settings:', data);
|
|
249
|
-
console.log('User ID:', variables.userId);
|
|
250
|
-
},
|
|
251
|
-
}
|
|
252
|
-
);
|
|
253
|
-
```
|
|
87
|
+
**Location**: `/Users/umituz/Desktop/github/umituz/apps/artificial_intelligence/npm-packages/react-native-settings/src/presentation/hooks/mutations/useUpdateSettingsMutation.ts`
|
|
254
88
|
|
|
255
|
-
|
|
89
|
+
**Variables**: `{ userId: string, settings: Partial<UserSettings> }`
|
|
90
|
+
**Returns**: `UpdateSettingsMutationResult` with mutate, isLoading, isError, error, data
|
|
256
91
|
|
|
257
|
-
|
|
92
|
+
**Use Cases**:
|
|
93
|
+
- Single setting updates (theme, language, etc.)
|
|
94
|
+
- Multiple setting updates in one operation
|
|
95
|
+
- Batch updates with user confirmation
|
|
258
96
|
|
|
259
|
-
|
|
260
|
-
const updateSettings = useUpdateSettingsMutation();
|
|
97
|
+
### useResetSettingsMutation
|
|
261
98
|
|
|
262
|
-
|
|
263
|
-
{ userId: 'user123', settings: { theme: 'dark' } },
|
|
264
|
-
{
|
|
265
|
-
onError: (error) => {
|
|
266
|
-
Alert.alert('Error', error.message);
|
|
267
|
-
},
|
|
268
|
-
}
|
|
269
|
-
);
|
|
270
|
-
```
|
|
99
|
+
Hook for resetting user settings to default values.
|
|
271
100
|
|
|
272
|
-
|
|
101
|
+
**Location**: `/Users/umituz/Desktop/github/umituz/apps/artificial_intelligence/npm-packages/react-native-settings/src/presentation/hooks/mutations/useResetSettingsMutation.ts`
|
|
273
102
|
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
```typescript
|
|
277
|
-
updateSettings.mutate(
|
|
278
|
-
{ userId: 'user123', settings: { theme: 'dark' } },
|
|
279
|
-
{
|
|
280
|
-
onMutate: async (variables) => {
|
|
281
|
-
// Cancel related queries
|
|
282
|
-
await queryClient.cancelQueries(['settings', variables.userId]);
|
|
283
|
-
|
|
284
|
-
// Snapshot previous value
|
|
285
|
-
const previous = queryClient.getQueryData(['settings', variables.userId]);
|
|
286
|
-
|
|
287
|
-
// Optimistically update
|
|
288
|
-
queryClient.setQueryData(['settings', variables.userId], (old: any) => ({
|
|
289
|
-
...old,
|
|
290
|
-
...variables.settings,
|
|
291
|
-
}));
|
|
292
|
-
|
|
293
|
-
// Return context with snapshot
|
|
294
|
-
return { previous };
|
|
295
|
-
},
|
|
296
|
-
}
|
|
297
|
-
);
|
|
298
|
-
```
|
|
103
|
+
**Variables**: `userId: string`
|
|
104
|
+
**Returns**: `ResetSettingsMutationResult` with mutate, isLoading, isError, error, data
|
|
299
105
|
|
|
300
|
-
|
|
106
|
+
**Use Cases**:
|
|
107
|
+
- Reset to defaults button
|
|
108
|
+
- User-initiated settings reset
|
|
109
|
+
- Troubleshooting settings issues
|
|
301
110
|
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
```typescript
|
|
305
|
-
updateSettings.mutate(
|
|
306
|
-
{ userId: 'user123', settings: { theme: 'dark' } },
|
|
307
|
-
{
|
|
308
|
-
onSettled: (data, error, variables) => {
|
|
309
|
-
// Always invalidate queries
|
|
310
|
-
queryClient.invalidateQueries(['settings', variables.userId]);
|
|
311
|
-
},
|
|
312
|
-
}
|
|
313
|
-
);
|
|
314
|
-
```
|
|
111
|
+
## Mutation Options
|
|
315
112
|
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
### Complete Form Handler
|
|
319
|
-
|
|
320
|
-
```tsx
|
|
321
|
-
function SettingsForm() {
|
|
322
|
-
const updateSettings = useUpdateSettingsMutation();
|
|
323
|
-
const [theme, setTheme] = useState('light');
|
|
324
|
-
const [language, setLanguage] = useState('en-US');
|
|
325
|
-
|
|
326
|
-
const handleSubmit = useCallback(() => {
|
|
327
|
-
updateSettings.mutate(
|
|
328
|
-
{
|
|
329
|
-
userId: 'user123',
|
|
330
|
-
settings: {
|
|
331
|
-
theme,
|
|
332
|
-
language,
|
|
333
|
-
notificationsEnabled: true,
|
|
334
|
-
},
|
|
335
|
-
},
|
|
336
|
-
{
|
|
337
|
-
onSuccess: () => {
|
|
338
|
-
Alert.alert('Success', 'Settings saved successfully');
|
|
339
|
-
},
|
|
340
|
-
onError: (error) => {
|
|
341
|
-
Alert.alert('Error', 'Failed to save settings');
|
|
342
|
-
},
|
|
343
|
-
}
|
|
344
|
-
);
|
|
345
|
-
}, [theme, language, updateSettings]);
|
|
346
|
-
|
|
347
|
-
return (
|
|
348
|
-
<View>
|
|
349
|
-
<ThemeSelector value={theme} onChange={setTheme} />
|
|
350
|
-
<LanguagePicker value={language} onChange={setLanguage} />
|
|
351
|
-
<Button
|
|
352
|
-
onPress={handleSubmit}
|
|
353
|
-
loading={updateSettings.isLoading}
|
|
354
|
-
title="Save Settings"
|
|
355
|
-
/>
|
|
356
|
-
</View>
|
|
357
|
-
);
|
|
358
|
-
}
|
|
359
|
-
```
|
|
113
|
+
### onSuccess
|
|
360
114
|
|
|
361
|
-
|
|
115
|
+
Callback executed when mutation succeeds. Use for:
|
|
116
|
+
- User feedback (success messages)
|
|
117
|
+
- Navigation after successful mutation
|
|
118
|
+
- Triggering side effects
|
|
362
119
|
|
|
363
|
-
|
|
364
|
-
function BatchUpdateExample() {
|
|
365
|
-
const updateSettings = useUpdateSettingsMutation();
|
|
120
|
+
### onError
|
|
366
121
|
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
{ notificationsEnabled: true },
|
|
372
|
-
];
|
|
122
|
+
Callback executed when mutation fails. Use for:
|
|
123
|
+
- Error logging
|
|
124
|
+
- User error notifications
|
|
125
|
+
- Cleanup after failed operations
|
|
373
126
|
|
|
374
|
-
|
|
375
|
-
for (const update of updates) {
|
|
376
|
-
await updateSettings.mutateAsync({
|
|
377
|
-
userId: 'user123',
|
|
378
|
-
settings: update,
|
|
379
|
-
});
|
|
380
|
-
}
|
|
127
|
+
### onMutate
|
|
381
128
|
|
|
382
|
-
|
|
383
|
-
|
|
129
|
+
Callback executed before mutation. Use for:
|
|
130
|
+
- Optimistic updates
|
|
131
|
+
- Canceling ongoing queries
|
|
132
|
+
- Context snapshots for rollback
|
|
384
133
|
|
|
385
|
-
|
|
386
|
-
}
|
|
387
|
-
```
|
|
134
|
+
### onSettled
|
|
388
135
|
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
const updateSettings = useUpdateSettingsMutation();
|
|
394
|
-
const debouncedUpdate = useMemo(
|
|
395
|
-
() => debounce((settings: Partial<UserSettings>) => {
|
|
396
|
-
updateSettings.mutate({
|
|
397
|
-
userId: 'user123',
|
|
398
|
-
settings,
|
|
399
|
-
});
|
|
400
|
-
}, 500),
|
|
401
|
-
[updateSettings]
|
|
402
|
-
);
|
|
403
|
-
|
|
404
|
-
const handleThemeChange = (theme: 'light' | 'dark') => {
|
|
405
|
-
debouncedUpdate({ theme });
|
|
406
|
-
};
|
|
407
|
-
|
|
408
|
-
return <ThemeSelector onChange={handleThemeChange} />;
|
|
409
|
-
}
|
|
410
|
-
```
|
|
136
|
+
Callback executed after mutation succeeds or fails. Use for:
|
|
137
|
+
- Query invalidation
|
|
138
|
+
- Cleanup operations
|
|
139
|
+
- Resetting UI states
|
|
411
140
|
|
|
412
141
|
## Best Practices
|
|
413
142
|
|
|
414
|
-
1. **
|
|
415
|
-
2. **
|
|
416
|
-
3. **
|
|
417
|
-
4. **
|
|
418
|
-
5. **Invalidation**: Invalidate queries after mutations
|
|
143
|
+
1. **Confirm Destructive Actions**: Always confirm reset operations with user
|
|
144
|
+
2. **Optimistic Updates**: Use onMutate for immediate UI feedback
|
|
145
|
+
3. **Error Handling**: Always handle errors gracefully with user-friendly messages
|
|
146
|
+
4. **Loading States**: Show loading indicators during mutations
|
|
147
|
+
5. **Query Invalidation**: Invalidate queries after mutations to refresh data
|
|
419
148
|
6. **Rollback**: Implement rollback for failed optimistic updates
|
|
420
|
-
7. **Type Safety**: Use TypeScript for mutation variables
|
|
421
|
-
|
|
422
|
-
## Related
|
|
423
|
-
|
|
424
|
-
- **Settings Queries**: Query hooks for fetching settings
|
|
425
|
-
- **useSettings**: Combined hook for settings management
|
|
426
|
-
- **Settings Repository**: Data persistence layer
|
|
149
|
+
7. **Type Safety**: Use TypeScript for mutation variables and results
|
|
427
150
|
|
|
428
151
|
## License
|
|
429
152
|
|