@mytechtoday/augment-extensions 0.1.0 → 0.1.2

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.
Files changed (102) hide show
  1. package/AGENTS.md +83 -3
  2. package/README.md +6 -5
  3. package/augment-extensions/coding-standards/python/README.md +44 -0
  4. package/augment-extensions/coding-standards/python/module.json +26 -0
  5. package/augment-extensions/coding-standards/python/rules/best-practices.md +232 -0
  6. package/augment-extensions/coding-standards/python/rules/code-organization.md +220 -0
  7. package/augment-extensions/coding-standards/python/rules/error-handling.md +221 -0
  8. package/augment-extensions/coding-standards/python/rules/naming-conventions.md +172 -0
  9. package/augment-extensions/coding-standards/python/rules/type-hints.md +188 -0
  10. package/augment-extensions/coding-standards/react/README.md +45 -0
  11. package/augment-extensions/coding-standards/react/module.json +27 -0
  12. package/augment-extensions/coding-standards/react/rules/component-patterns.md +214 -0
  13. package/augment-extensions/coding-standards/react/rules/hooks-best-practices.md +235 -0
  14. package/augment-extensions/coding-standards/react/rules/performance.md +300 -0
  15. package/augment-extensions/coding-standards/react/rules/state-management.md +265 -0
  16. package/augment-extensions/coding-standards/react/rules/typescript-react.md +271 -0
  17. package/augment-extensions/domain-rules/api-design/README.md +41 -0
  18. package/augment-extensions/domain-rules/api-design/module.json +27 -0
  19. package/augment-extensions/domain-rules/api-design/rules/authentication.md +263 -0
  20. package/augment-extensions/domain-rules/api-design/rules/documentation.md +395 -0
  21. package/augment-extensions/domain-rules/api-design/rules/error-handling.md +290 -0
  22. package/augment-extensions/domain-rules/api-design/rules/graphql-api.md +313 -0
  23. package/augment-extensions/domain-rules/api-design/rules/rest-api.md +214 -0
  24. package/augment-extensions/domain-rules/api-design/rules/versioning.md +268 -0
  25. package/augment-extensions/domain-rules/security/README.md +41 -0
  26. package/augment-extensions/domain-rules/security/module.json +28 -0
  27. package/augment-extensions/domain-rules/security/rules/authentication-security.md +361 -0
  28. package/augment-extensions/domain-rules/security/rules/encryption.md +208 -0
  29. package/augment-extensions/domain-rules/security/rules/input-validation.md +294 -0
  30. package/augment-extensions/domain-rules/security/rules/owasp-top-10.md +339 -0
  31. package/augment-extensions/domain-rules/security/rules/secure-coding.md +293 -0
  32. package/augment-extensions/domain-rules/security/rules/web-security.md +268 -0
  33. package/augment-extensions/examples/design-patterns/README.md +37 -0
  34. package/augment-extensions/examples/design-patterns/examples/behavioral-patterns.md +370 -0
  35. package/augment-extensions/examples/design-patterns/examples/creational-patterns.md +250 -0
  36. package/augment-extensions/examples/design-patterns/examples/structural-patterns.md +264 -0
  37. package/augment-extensions/examples/design-patterns/module.json +27 -0
  38. package/{modules → augment-extensions}/workflows/beads/examples/complete-workflow-example.md +5 -5
  39. package/{modules → augment-extensions}/workflows/beads/rules/file-format.md +45 -1
  40. package/{modules → augment-extensions}/workflows/beads/rules/workflow.md +41 -0
  41. package/{modules → augment-extensions}/workflows/openspec/examples/complete-change-example.md +14 -0
  42. package/{modules → augment-extensions}/workflows/openspec/rules/spec-format.md +44 -1
  43. package/{modules → augment-extensions}/workflows/openspec/rules/workflow.md +25 -0
  44. package/cli/dist/cli.js +69 -1
  45. package/cli/dist/cli.js.map +1 -1
  46. package/cli/dist/commands/coord.d.ts +30 -0
  47. package/cli/dist/commands/coord.d.ts.map +1 -0
  48. package/cli/dist/commands/coord.js +150 -0
  49. package/cli/dist/commands/coord.js.map +1 -0
  50. package/cli/dist/commands/link.js +1 -1
  51. package/cli/dist/commands/link.js.map +1 -1
  52. package/cli/dist/commands/list.js +1 -1
  53. package/cli/dist/commands/list.js.map +1 -1
  54. package/cli/dist/commands/search.d.ts.map +1 -1
  55. package/cli/dist/commands/search.js +107 -5
  56. package/cli/dist/commands/search.js.map +1 -1
  57. package/cli/dist/commands/show.js +1 -1
  58. package/cli/dist/commands/show.js.map +1 -1
  59. package/cli/dist/commands/sync.d.ts +26 -0
  60. package/cli/dist/commands/sync.d.ts.map +1 -0
  61. package/cli/dist/commands/sync.js +106 -0
  62. package/cli/dist/commands/sync.js.map +1 -0
  63. package/cli/dist/commands/update.d.ts.map +1 -1
  64. package/cli/dist/commands/update.js +132 -7
  65. package/cli/dist/commands/update.js.map +1 -1
  66. package/cli/dist/utils/auto-sync.d.ts +34 -0
  67. package/cli/dist/utils/auto-sync.d.ts.map +1 -0
  68. package/cli/dist/utils/auto-sync.js +172 -0
  69. package/cli/dist/utils/auto-sync.js.map +1 -0
  70. package/cli/dist/utils/beads-sync.d.ts +51 -0
  71. package/cli/dist/utils/beads-sync.d.ts.map +1 -0
  72. package/cli/dist/utils/beads-sync.js +171 -0
  73. package/cli/dist/utils/beads-sync.js.map +1 -0
  74. package/cli/dist/utils/coordination-queries.d.ts +79 -0
  75. package/cli/dist/utils/coordination-queries.d.ts.map +1 -0
  76. package/cli/dist/utils/coordination-queries.js +155 -0
  77. package/cli/dist/utils/coordination-queries.js.map +1 -0
  78. package/cli/dist/utils/file-tracking.d.ts +42 -0
  79. package/cli/dist/utils/file-tracking.d.ts.map +1 -0
  80. package/cli/dist/utils/file-tracking.js +155 -0
  81. package/cli/dist/utils/file-tracking.js.map +1 -0
  82. package/cli/dist/utils/migrate.d.ts +25 -0
  83. package/cli/dist/utils/migrate.d.ts.map +1 -0
  84. package/cli/dist/utils/migrate.js +204 -0
  85. package/cli/dist/utils/migrate.js.map +1 -0
  86. package/cli/dist/utils/openspec-sync.d.ts +48 -0
  87. package/cli/dist/utils/openspec-sync.d.ts.map +1 -0
  88. package/cli/dist/utils/openspec-sync.js +167 -0
  89. package/cli/dist/utils/openspec-sync.js.map +1 -0
  90. package/{MODULES.md → modules.md} +1 -1
  91. package/package.json +9 -7
  92. /package/{modules → augment-extensions}/coding-standards/typescript/README.md +0 -0
  93. /package/{modules → augment-extensions}/coding-standards/typescript/module.json +0 -0
  94. /package/{modules → augment-extensions}/coding-standards/typescript/rules/naming-conventions.md +0 -0
  95. /package/{modules → augment-extensions}/workflows/beads/README.md +0 -0
  96. /package/{modules → augment-extensions}/workflows/beads/module.json +0 -0
  97. /package/{modules → augment-extensions}/workflows/beads/rules/best-practices.md +0 -0
  98. /package/{modules → augment-extensions}/workflows/beads/rules/manual-setup.md +0 -0
  99. /package/{modules → augment-extensions}/workflows/openspec/README.md +0 -0
  100. /package/{modules → augment-extensions}/workflows/openspec/module.json +0 -0
  101. /package/{modules → augment-extensions}/workflows/openspec/rules/best-practices.md +0 -0
  102. /package/{modules → augment-extensions}/workflows/openspec/rules/manual-setup.md +0 -0
@@ -0,0 +1,300 @@
1
+ # React Performance Optimization
2
+
3
+ Techniques for optimizing React application performance.
4
+
5
+ ## React.memo
6
+
7
+ Prevent unnecessary re-renders of components.
8
+
9
+ ```tsx
10
+ // Good - Memoize expensive components
11
+ interface UserCardProps {
12
+ user: User;
13
+ onEdit: (id: string) => void;
14
+ }
15
+
16
+ export const UserCard = React.memo<UserCardProps>(({ user, onEdit }) => {
17
+ return (
18
+ <div className="user-card">
19
+ <h3>{user.name}</h3>
20
+ <button onClick={() => onEdit(user.id)}>Edit</button>
21
+ </div>
22
+ );
23
+ });
24
+
25
+ // Good - Custom comparison function
26
+ export const UserCard = React.memo<UserCardProps>(
27
+ ({ user, onEdit }) => {
28
+ return <div>{user.name}</div>;
29
+ },
30
+ (prevProps, nextProps) => {
31
+ return prevProps.user.id === nextProps.user.id;
32
+ }
33
+ );
34
+
35
+ // Bad - Memoizing everything unnecessarily
36
+ export const SimpleText = React.memo(({ text }: { text: string }) => {
37
+ return <span>{text}</span>; // Too simple to memoize
38
+ });
39
+ ```
40
+
41
+ ## useCallback
42
+
43
+ Memoize callback functions to prevent child re-renders.
44
+
45
+ ```tsx
46
+ // Good - Memoize callbacks passed to memoized children
47
+ const ParentComponent: React.FC = () => {
48
+ const [items, setItems] = useState<Item[]>([]);
49
+
50
+ const handleItemClick = useCallback((id: string) => {
51
+ console.log('Clicked:', id);
52
+ }, []);
53
+
54
+ const handleItemDelete = useCallback((id: string) => {
55
+ setItems(prev => prev.filter(item => item.id !== id));
56
+ }, []);
57
+
58
+ return (
59
+ <>
60
+ {items.map(item => (
61
+ <MemoizedItem
62
+ key={item.id}
63
+ item={item}
64
+ onClick={handleItemClick}
65
+ onDelete={handleItemDelete}
66
+ />
67
+ ))}
68
+ </>
69
+ );
70
+ };
71
+ ```
72
+
73
+ ## useMemo
74
+
75
+ Memoize expensive computations.
76
+
77
+ ```tsx
78
+ // Good - Memoize expensive calculations
79
+ const ExpensiveComponent: React.FC<{ items: Item[] }> = ({ items }) => {
80
+ const sortedAndFilteredItems = useMemo(() => {
81
+ return items
82
+ .filter(item => item.active)
83
+ .sort((a, b) => a.priority - b.priority);
84
+ }, [items]);
85
+
86
+ const statistics = useMemo(() => {
87
+ return {
88
+ total: items.length,
89
+ active: items.filter(i => i.active).length,
90
+ average: items.reduce((sum, i) => sum + i.value, 0) / items.length
91
+ };
92
+ }, [items]);
93
+
94
+ return (
95
+ <>
96
+ <Stats data={statistics} />
97
+ <ItemList items={sortedAndFilteredItems} />
98
+ </>
99
+ );
100
+ };
101
+ ```
102
+
103
+ ## Code Splitting
104
+
105
+ Split code to reduce initial bundle size.
106
+
107
+ ```tsx
108
+ // Good - Lazy load routes
109
+ import { lazy, Suspense } from 'react';
110
+
111
+ const Dashboard = lazy(() => import('./pages/Dashboard'));
112
+ const Settings = lazy(() => import('./pages/Settings'));
113
+ const Profile = lazy(() => import('./pages/Profile'));
114
+
115
+ const App: React.FC = () => (
116
+ <Suspense fallback={<LoadingSpinner />}>
117
+ <Routes>
118
+ <Route path="/dashboard" element={<Dashboard />} />
119
+ <Route path="/settings" element={<Settings />} />
120
+ <Route path="/profile" element={<Profile />} />
121
+ </Routes>
122
+ </Suspense>
123
+ );
124
+
125
+ // Good - Lazy load heavy components
126
+ const HeavyChart = lazy(() => import('./components/HeavyChart'));
127
+
128
+ const Analytics: React.FC = () => (
129
+ <Suspense fallback={<ChartSkeleton />}>
130
+ <HeavyChart data={data} />
131
+ </Suspense>
132
+ );
133
+ ```
134
+
135
+ ## Virtualization
136
+
137
+ Render only visible items in long lists.
138
+
139
+ ```tsx
140
+ // Good - Use react-window for long lists
141
+ import { FixedSizeList } from 'react-window';
142
+
143
+ const VirtualizedList: React.FC<{ items: Item[] }> = ({ items }) => {
144
+ const Row = ({ index, style }: { index: number; style: React.CSSProperties }) => (
145
+ <div style={style}>
146
+ <ItemCard item={items[index]} />
147
+ </div>
148
+ );
149
+
150
+ return (
151
+ <FixedSizeList
152
+ height={600}
153
+ itemCount={items.length}
154
+ itemSize={80}
155
+ width="100%"
156
+ >
157
+ {Row}
158
+ </FixedSizeList>
159
+ );
160
+ };
161
+ ```
162
+
163
+ ## Debouncing and Throttling
164
+
165
+ Limit expensive operations.
166
+
167
+ ```tsx
168
+ // Good - Debounce search input
169
+ import { useDebouncedCallback } from 'use-debounce';
170
+
171
+ const SearchInput: React.FC = () => {
172
+ const [query, setQuery] = useState('');
173
+
174
+ const debouncedSearch = useDebouncedCallback(
175
+ (value: string) => {
176
+ performSearch(value);
177
+ },
178
+ 500
179
+ );
180
+
181
+ const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
182
+ const value = e.target.value;
183
+ setQuery(value);
184
+ debouncedSearch(value);
185
+ };
186
+
187
+ return <input value={query} onChange={handleChange} />;
188
+ };
189
+
190
+ // Good - Throttle scroll handler
191
+ import { useThrottledCallback } from 'use-debounce';
192
+
193
+ const ScrollTracker: React.FC = () => {
194
+ const throttledScroll = useThrottledCallback(
195
+ () => {
196
+ trackScrollPosition(window.scrollY);
197
+ },
198
+ 200
199
+ );
200
+
201
+ useEffect(() => {
202
+ window.addEventListener('scroll', throttledScroll);
203
+ return () => window.removeEventListener('scroll', throttledScroll);
204
+ }, [throttledScroll]);
205
+
206
+ return null;
207
+ };
208
+ ```
209
+
210
+ ## Avoid Inline Objects and Functions
211
+
212
+ Prevent unnecessary re-renders.
213
+
214
+ ```tsx
215
+ // Bad - Inline objects cause re-renders
216
+ const Parent: React.FC = () => (
217
+ <Child style={{ margin: 10 }} /> // New object every render
218
+ );
219
+
220
+ // Good - Define outside or memoize
221
+ const childStyle = { margin: 10 };
222
+ const Parent: React.FC = () => (
223
+ <Child style={childStyle} />
224
+ );
225
+
226
+ // Bad - Inline functions
227
+ const Parent: React.FC = () => (
228
+ <Child onClick={() => console.log('clicked')} /> // New function every render
229
+ );
230
+
231
+ // Good - useCallback
232
+ const Parent: React.FC = () => {
233
+ const handleClick = useCallback(() => {
234
+ console.log('clicked');
235
+ }, []);
236
+
237
+ return <Child onClick={handleClick} />;
238
+ };
239
+ ```
240
+
241
+ ## Image Optimization
242
+
243
+ Optimize images for better performance.
244
+
245
+ ```tsx
246
+ // Good - Lazy load images
247
+ const LazyImage: React.FC<{ src: string; alt: string }> = ({ src, alt }) => {
248
+ return <img src={src} alt={alt} loading="lazy" />;
249
+ };
250
+
251
+ // Good - Use next/image for Next.js
252
+ import Image from 'next/image';
253
+
254
+ const OptimizedImage: React.FC = () => (
255
+ <Image
256
+ src="/photo.jpg"
257
+ alt="Photo"
258
+ width={500}
259
+ height={300}
260
+ placeholder="blur"
261
+ />
262
+ );
263
+ ```
264
+
265
+ ## Profiling
266
+
267
+ Use React DevTools Profiler to identify performance issues.
268
+
269
+ ```tsx
270
+ // Good - Wrap components to profile
271
+ import { Profiler } from 'react';
272
+
273
+ const onRenderCallback = (
274
+ id: string,
275
+ phase: 'mount' | 'update',
276
+ actualDuration: number
277
+ ) => {
278
+ console.log(`${id} (${phase}) took ${actualDuration}ms`);
279
+ };
280
+
281
+ const App: React.FC = () => (
282
+ <Profiler id="App" onRender={onRenderCallback}>
283
+ <Dashboard />
284
+ </Profiler>
285
+ );
286
+ ```
287
+
288
+ ## Best Practices
289
+
290
+ 1. **Profile first** - Use React DevTools before optimizing
291
+ 2. **Use React.memo** - For expensive components
292
+ 3. **Memoize callbacks** - Use useCallback for child props
293
+ 4. **Memoize computations** - Use useMemo for expensive calculations
294
+ 5. **Code split** - Lazy load routes and heavy components
295
+ 6. **Virtualize lists** - Use react-window for long lists
296
+ 7. **Debounce inputs** - Limit expensive operations
297
+ 8. **Avoid inline objects** - Define outside or memoize
298
+ 9. **Optimize images** - Use lazy loading and optimization
299
+ 10. **Monitor bundle size** - Use webpack-bundle-analyzer
300
+
@@ -0,0 +1,265 @@
1
+ # React State Management
2
+
3
+ Patterns for managing state in React applications.
4
+
5
+ ## Local State (useState)
6
+
7
+ Use for component-specific state.
8
+
9
+ ```tsx
10
+ // Good - Local UI state
11
+ const SearchInput: React.FC = () => {
12
+ const [query, setQuery] = useState('');
13
+ const [isFocused, setIsFocused] = useState(false);
14
+
15
+ return (
16
+ <input
17
+ value={query}
18
+ onChange={(e) => setQuery(e.target.value)}
19
+ onFocus={() => setIsFocused(true)}
20
+ onBlur={() => setIsFocused(false)}
21
+ />
22
+ );
23
+ };
24
+ ```
25
+
26
+ ## Lifting State Up
27
+
28
+ Share state between components by moving it to common parent.
29
+
30
+ ```tsx
31
+ // Good - Shared state in parent
32
+ const UserForm: React.FC = () => {
33
+ const [formData, setFormData] = useState({ name: '', email: '' });
34
+
35
+ return (
36
+ <>
37
+ <NameInput
38
+ value={formData.name}
39
+ onChange={(name) => setFormData(prev => ({ ...prev, name }))}
40
+ />
41
+ <EmailInput
42
+ value={formData.email}
43
+ onChange={(email) => setFormData(prev => ({ ...prev, email }))}
44
+ />
45
+ <FormPreview data={formData} />
46
+ </>
47
+ );
48
+ };
49
+ ```
50
+
51
+ ## Context API
52
+
53
+ Use for global or deeply nested state.
54
+
55
+ ```tsx
56
+ // Good - Context for theme
57
+ interface ThemeContextValue {
58
+ theme: 'light' | 'dark';
59
+ toggleTheme: () => void;
60
+ }
61
+
62
+ const ThemeContext = createContext<ThemeContextValue | undefined>(undefined);
63
+
64
+ export const ThemeProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
65
+ const [theme, setTheme] = useState<'light' | 'dark'>('light');
66
+
67
+ const toggleTheme = useCallback(() => {
68
+ setTheme(prev => prev === 'light' ? 'dark' : 'light');
69
+ }, []);
70
+
71
+ const value = useMemo(() => ({ theme, toggleTheme }), [theme, toggleTheme]);
72
+
73
+ return (
74
+ <ThemeContext.Provider value={value}>
75
+ {children}
76
+ </ThemeContext.Provider>
77
+ );
78
+ };
79
+
80
+ export const useTheme = () => {
81
+ const context = useContext(ThemeContext);
82
+ if (!context) throw new Error('useTheme must be used within ThemeProvider');
83
+ return context;
84
+ };
85
+ ```
86
+
87
+ ## useReducer
88
+
89
+ Use for complex state logic.
90
+
91
+ ```tsx
92
+ // Good - Complex state with useReducer
93
+ interface State {
94
+ data: User[];
95
+ loading: boolean;
96
+ error: Error | null;
97
+ page: number;
98
+ }
99
+
100
+ type Action =
101
+ | { type: 'FETCH_START' }
102
+ | { type: 'FETCH_SUCCESS'; payload: User[] }
103
+ | { type: 'FETCH_ERROR'; payload: Error }
104
+ | { type: 'SET_PAGE'; payload: number };
105
+
106
+ const reducer = (state: State, action: Action): State => {
107
+ switch (action.type) {
108
+ case 'FETCH_START':
109
+ return { ...state, loading: true, error: null };
110
+ case 'FETCH_SUCCESS':
111
+ return { ...state, loading: false, data: action.payload };
112
+ case 'FETCH_ERROR':
113
+ return { ...state, loading: false, error: action.payload };
114
+ case 'SET_PAGE':
115
+ return { ...state, page: action.payload };
116
+ default:
117
+ return state;
118
+ }
119
+ };
120
+
121
+ const UserList: React.FC = () => {
122
+ const [state, dispatch] = useReducer(reducer, {
123
+ data: [],
124
+ loading: false,
125
+ error: null,
126
+ page: 1
127
+ });
128
+
129
+ useEffect(() => {
130
+ const fetchUsers = async () => {
131
+ dispatch({ type: 'FETCH_START' });
132
+ try {
133
+ const users = await api.getUsers(state.page);
134
+ dispatch({ type: 'FETCH_SUCCESS', payload: users });
135
+ } catch (error) {
136
+ dispatch({ type: 'FETCH_ERROR', payload: error as Error });
137
+ }
138
+ };
139
+
140
+ fetchUsers();
141
+ }, [state.page]);
142
+
143
+ return (
144
+ <>
145
+ {state.loading && <Spinner />}
146
+ {state.error && <Error message={state.error.message} />}
147
+ <UserGrid users={state.data} />
148
+ <Pagination
149
+ page={state.page}
150
+ onPageChange={(page) => dispatch({ type: 'SET_PAGE', payload: page })}
151
+ />
152
+ </>
153
+ );
154
+ };
155
+ ```
156
+
157
+ ## Zustand (Recommended)
158
+
159
+ Simple, fast state management library.
160
+
161
+ ```tsx
162
+ // Good - Zustand store
163
+ import create from 'zustand';
164
+
165
+ interface UserStore {
166
+ users: User[];
167
+ loading: boolean;
168
+ error: Error | null;
169
+ fetchUsers: () => Promise<void>;
170
+ addUser: (user: User) => void;
171
+ removeUser: (id: string) => void;
172
+ }
173
+
174
+ export const useUserStore = create<UserStore>((set) => ({
175
+ users: [],
176
+ loading: false,
177
+ error: null,
178
+
179
+ fetchUsers: async () => {
180
+ set({ loading: true, error: null });
181
+ try {
182
+ const users = await api.getUsers();
183
+ set({ users, loading: false });
184
+ } catch (error) {
185
+ set({ error: error as Error, loading: false });
186
+ }
187
+ },
188
+
189
+ addUser: (user) => set((state) => ({
190
+ users: [...state.users, user]
191
+ })),
192
+
193
+ removeUser: (id) => set((state) => ({
194
+ users: state.users.filter(u => u.id !== id)
195
+ }))
196
+ }));
197
+
198
+ // Usage
199
+ const UserList: React.FC = () => {
200
+ const { users, loading, fetchUsers } = useUserStore();
201
+
202
+ useEffect(() => {
203
+ fetchUsers();
204
+ }, [fetchUsers]);
205
+
206
+ return <UserGrid users={users} loading={loading} />;
207
+ };
208
+ ```
209
+
210
+ ## React Query
211
+
212
+ For server state management.
213
+
214
+ ```tsx
215
+ // Good - React Query for data fetching
216
+ import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
217
+
218
+ const useUsers = () => {
219
+ return useQuery({
220
+ queryKey: ['users'],
221
+ queryFn: () => api.getUsers()
222
+ });
223
+ };
224
+
225
+ const useCreateUser = () => {
226
+ const queryClient = useQueryClient();
227
+
228
+ return useMutation({
229
+ mutationFn: (user: CreateUserInput) => api.createUser(user),
230
+ onSuccess: () => {
231
+ queryClient.invalidateQueries({ queryKey: ['users'] });
232
+ }
233
+ });
234
+ };
235
+
236
+ // Usage
237
+ const UserList: React.FC = () => {
238
+ const { data: users, isLoading, error } = useUsers();
239
+ const createUser = useCreateUser();
240
+
241
+ if (isLoading) return <Spinner />;
242
+ if (error) return <Error message={error.message} />;
243
+
244
+ return (
245
+ <>
246
+ <UserGrid users={users} />
247
+ <CreateUserForm onSubmit={createUser.mutate} />
248
+ </>
249
+ );
250
+ };
251
+ ```
252
+
253
+ ## Best Practices
254
+
255
+ 1. **Start with local state** - Use useState for component state
256
+ 2. **Lift state up** - When multiple components need it
257
+ 3. **Use Context sparingly** - For truly global state (theme, auth)
258
+ 4. **Use useReducer** - For complex state logic
259
+ 5. **Consider Zustand** - For client state management
260
+ 6. **Use React Query** - For server state (data fetching)
261
+ 7. **Avoid prop drilling** - Use Context or state management
262
+ 8. **Keep state minimal** - Derive values when possible
263
+ 9. **Normalize data** - Avoid nested state structures
264
+ 10. **Type everything** - Use TypeScript for all state
265
+