mcp-probe-kit 3.0.14 → 3.0.16
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 +17 -11
- package/build/lib/__tests__/gitnexus-bridge.unit.test.js +9 -1
- package/build/lib/gitnexus-bridge.d.ts +1 -0
- package/build/lib/gitnexus-bridge.js +29 -1
- package/build/lib/skill-bridge.d.ts +31 -0
- package/build/lib/skill-bridge.js +100 -0
- package/build/resources/ui-ux-data/charts.json +302 -0
- package/build/resources/ui-ux-data/colors.json +1058 -0
- package/build/resources/ui-ux-data/icons.json +1102 -0
- package/build/resources/ui-ux-data/landing.json +262 -0
- package/build/resources/ui-ux-data/metadata.json +6 -0
- package/build/resources/ui-ux-data/products.json +1058 -0
- package/build/resources/ui-ux-data/react-performance.json +574 -0
- package/build/resources/ui-ux-data/stacks/astro.json +266 -0
- package/build/resources/ui-ux-data/stacks/flutter.json +626 -0
- package/build/resources/ui-ux-data/stacks/html-tailwind.json +662 -0
- package/build/resources/ui-ux-data/stacks/jetpack-compose.json +626 -0
- package/build/resources/ui-ux-data/stacks/nextjs.json +218 -0
- package/build/resources/ui-ux-data/stacks/nuxt-ui.json +14 -0
- package/build/resources/ui-ux-data/stacks/nuxtjs.json +182 -0
- package/build/resources/ui-ux-data/stacks/react-native.json +350 -0
- package/build/resources/ui-ux-data/stacks/react.json +530 -0
- package/build/resources/ui-ux-data/stacks/shadcn.json +566 -0
- package/build/resources/ui-ux-data/stacks/svelte.json +134 -0
- package/build/resources/ui-ux-data/stacks/swiftui.json +26 -0
- package/build/resources/ui-ux-data/stacks/vue.json +170 -0
- package/build/resources/ui-ux-data/styles.json +1610 -0
- package/build/resources/ui-ux-data/typography.json +743 -0
- package/build/resources/ui-ux-data/ui-reasoning.json +1431 -0
- package/build/resources/ui-ux-data/ux-guidelines.json +1190 -0
- package/build/resources/ui-ux-data/web-interface.json +389 -0
- package/build/schemas/ui-ux-schemas.js +1 -1
- package/build/tools/start_product.js +8 -1
- package/build/tools/start_ui.js +14 -3
- package/build/tools/ui-ux-tools.js +21 -17
- package/build/utils/ui-data-loader.d.ts +18 -2
- package/build/utils/ui-data-loader.js +74 -12
- package/docs/i18n/en.json +4 -2
- package/docs/i18n/ja.json +4 -2
- package/docs/i18n/ko.json +4 -2
- package/docs/i18n/zh-CN.json +4 -2
- package/docs/pages/getting-started.html +3 -0
- package/package.json +2 -1
|
@@ -0,0 +1,530 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"No": "1",
|
|
4
|
+
"Category": "State",
|
|
5
|
+
"Guideline": "Use useState for local state",
|
|
6
|
+
"Description": "Simple component state should use useState hook",
|
|
7
|
+
"Do": "useState for form inputs toggles counters",
|
|
8
|
+
"Don't": "Class components this.state",
|
|
9
|
+
"Code Good": "const [count, setCount] = useState(0)",
|
|
10
|
+
"Code Bad": "this.state = { count: 0 }",
|
|
11
|
+
"Severity": "Medium",
|
|
12
|
+
"Docs URL": "https://react.dev/reference/react/useState"
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"No": "2",
|
|
16
|
+
"Category": "State",
|
|
17
|
+
"Guideline": "Lift state up when needed",
|
|
18
|
+
"Description": "Share state between siblings by lifting to parent",
|
|
19
|
+
"Do": "Lift shared state to common ancestor",
|
|
20
|
+
"Don't": "Prop drilling through many levels",
|
|
21
|
+
"Code Good": "Parent holds state passes down",
|
|
22
|
+
"Code Bad": "Deep prop chains",
|
|
23
|
+
"Severity": "Medium",
|
|
24
|
+
"Docs URL": "https://react.dev/learn/sharing-state-between-components"
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"No": "3",
|
|
28
|
+
"Category": "State",
|
|
29
|
+
"Guideline": "Use useReducer for complex state",
|
|
30
|
+
"Description": "Complex state logic benefits from reducer pattern",
|
|
31
|
+
"Do": "useReducer for state with multiple sub-values",
|
|
32
|
+
"Don't": "Multiple useState for related values",
|
|
33
|
+
"Code Good": "useReducer with action types",
|
|
34
|
+
"Code Bad": "5+ useState calls that update together",
|
|
35
|
+
"Severity": "Medium",
|
|
36
|
+
"Docs URL": "https://react.dev/reference/react/useReducer"
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"No": "4",
|
|
40
|
+
"Category": "State",
|
|
41
|
+
"Guideline": "Avoid unnecessary state",
|
|
42
|
+
"Description": "Derive values from existing state when possible",
|
|
43
|
+
"Do": "Compute derived values in render",
|
|
44
|
+
"Don't": "Store derivable values in state",
|
|
45
|
+
"Code Good": "const total = items.reduce(...)",
|
|
46
|
+
"Code Bad": "const [total, setTotal] = useState(0)",
|
|
47
|
+
"Severity": "High",
|
|
48
|
+
"Docs URL": "https://react.dev/learn/choosing-the-state-structure"
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"No": "5",
|
|
52
|
+
"Category": "State",
|
|
53
|
+
"Guideline": "Initialize state lazily",
|
|
54
|
+
"Description": "Use function form for expensive initial state",
|
|
55
|
+
"Do": "useState(() => computeExpensive())",
|
|
56
|
+
"Don't": "useState(computeExpensive())",
|
|
57
|
+
"Code Good": "useState(() => JSON.parse(data))",
|
|
58
|
+
"Code Bad": "useState(JSON.parse(data))",
|
|
59
|
+
"Severity": "Medium",
|
|
60
|
+
"Docs URL": "https://react.dev/reference/react/useState#avoiding-recreating-the-initial-state"
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
"No": "6",
|
|
64
|
+
"Category": "Effects",
|
|
65
|
+
"Guideline": "Clean up effects",
|
|
66
|
+
"Description": "Return cleanup function for subscriptions timers",
|
|
67
|
+
"Do": "Return cleanup function in useEffect",
|
|
68
|
+
"Don't": "No cleanup for subscriptions",
|
|
69
|
+
"Code Good": "useEffect(() => { sub(); return unsub; })",
|
|
70
|
+
"Code Bad": "useEffect(() => { subscribe(); })",
|
|
71
|
+
"Severity": "High",
|
|
72
|
+
"Docs URL": "https://react.dev/reference/react/useEffect#connecting-to-an-external-system"
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
"No": "7",
|
|
76
|
+
"Category": "Effects",
|
|
77
|
+
"Guideline": "Specify dependencies correctly",
|
|
78
|
+
"Description": "Include all values used inside effect in deps array",
|
|
79
|
+
"Do": "All referenced values in dependency array",
|
|
80
|
+
"Don't": "Empty deps with external references",
|
|
81
|
+
"Code Good": "[value] when using value in effect",
|
|
82
|
+
"Code Bad": "[] when using props/state in effect",
|
|
83
|
+
"Severity": "High",
|
|
84
|
+
"Docs URL": "https://react.dev/reference/react/useEffect#specifying-reactive-dependencies"
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
"No": "8",
|
|
88
|
+
"Category": "Effects",
|
|
89
|
+
"Guideline": "Avoid unnecessary effects",
|
|
90
|
+
"Description": "Don't use effects for transforming data or events",
|
|
91
|
+
"Do": "Transform data during render handle events directly",
|
|
92
|
+
"Don't": "useEffect for derived state or event handling",
|
|
93
|
+
"Code Good": "const filtered = items.filter(...)",
|
|
94
|
+
"Code Bad": "useEffect(() => setFiltered(items.filter(...)))",
|
|
95
|
+
"Severity": "High",
|
|
96
|
+
"Docs URL": "https://react.dev/learn/you-might-not-need-an-effect"
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
"No": "9",
|
|
100
|
+
"Category": "Effects",
|
|
101
|
+
"Guideline": "Use refs for non-reactive values",
|
|
102
|
+
"Description": "Store values that don't trigger re-renders in refs",
|
|
103
|
+
"Do": "useRef for interval IDs DOM elements",
|
|
104
|
+
"Don't": "useState for values that don't need render",
|
|
105
|
+
"Code Good": "const intervalRef = useRef(null)",
|
|
106
|
+
"Code Bad": "const [intervalId, setIntervalId] = useState()",
|
|
107
|
+
"Severity": "Medium",
|
|
108
|
+
"Docs URL": "https://react.dev/reference/react/useRef"
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
"No": "10",
|
|
112
|
+
"Category": "Rendering",
|
|
113
|
+
"Guideline": "Use keys properly",
|
|
114
|
+
"Description": "Stable unique keys for list items",
|
|
115
|
+
"Do": "Use stable IDs as keys",
|
|
116
|
+
"Don't": "Array index as key for dynamic lists",
|
|
117
|
+
"Code Good": "key={item.id}",
|
|
118
|
+
"Code Bad": "key={index}",
|
|
119
|
+
"Severity": "High",
|
|
120
|
+
"Docs URL": "https://react.dev/learn/rendering-lists#keeping-list-items-in-order-with-key"
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
"No": "11",
|
|
124
|
+
"Category": "Rendering",
|
|
125
|
+
"Guideline": "Memoize expensive calculations",
|
|
126
|
+
"Description": "Use useMemo for costly computations",
|
|
127
|
+
"Do": "useMemo for expensive filtering/sorting",
|
|
128
|
+
"Don't": "Recalculate every render",
|
|
129
|
+
"Code Good": "useMemo(() => expensive(), [deps])",
|
|
130
|
+
"Code Bad": "const result = expensiveCalc()",
|
|
131
|
+
"Severity": "Medium",
|
|
132
|
+
"Docs URL": "https://react.dev/reference/react/useMemo"
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
"No": "12",
|
|
136
|
+
"Category": "Rendering",
|
|
137
|
+
"Guideline": "Memoize callbacks passed to children",
|
|
138
|
+
"Description": "Use useCallback for functions passed as props",
|
|
139
|
+
"Do": "useCallback for handlers passed to memoized children",
|
|
140
|
+
"Don't": "New function reference every render",
|
|
141
|
+
"Code Good": "useCallback(() => {}, [deps])",
|
|
142
|
+
"Code Bad": "const handler = () => {}",
|
|
143
|
+
"Severity": "Medium",
|
|
144
|
+
"Docs URL": "https://react.dev/reference/react/useCallback"
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
"No": "13",
|
|
148
|
+
"Category": "Rendering",
|
|
149
|
+
"Guideline": "Use React.memo wisely",
|
|
150
|
+
"Description": "Wrap components that render often with same props",
|
|
151
|
+
"Do": "memo for pure components with stable props",
|
|
152
|
+
"Don't": "memo everything or nothing",
|
|
153
|
+
"Code Good": "memo(ExpensiveList)",
|
|
154
|
+
"Code Bad": "memo(SimpleButton)",
|
|
155
|
+
"Severity": "Low",
|
|
156
|
+
"Docs URL": "https://react.dev/reference/react/memo"
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
"No": "14",
|
|
160
|
+
"Category": "Rendering",
|
|
161
|
+
"Guideline": "Avoid inline object/array creation in JSX",
|
|
162
|
+
"Description": "Create objects outside render or memoize",
|
|
163
|
+
"Do": "Define style objects outside component",
|
|
164
|
+
"Don't": "Inline objects in props",
|
|
165
|
+
"Code Good": "<div style={styles.container}>",
|
|
166
|
+
"Code Bad": "<div style={{ margin: 10 }}>",
|
|
167
|
+
"Severity": "Medium",
|
|
168
|
+
"Docs URL": ""
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
"No": "15",
|
|
172
|
+
"Category": "Components",
|
|
173
|
+
"Guideline": "Keep components small and focused",
|
|
174
|
+
"Description": "Single responsibility for each component",
|
|
175
|
+
"Do": "One concern per component",
|
|
176
|
+
"Don't": "Large multi-purpose components",
|
|
177
|
+
"Code Good": "<UserAvatar /><UserName />",
|
|
178
|
+
"Code Bad": "<UserCard /> with 500 lines",
|
|
179
|
+
"Severity": "Medium",
|
|
180
|
+
"Docs URL": ""
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
"No": "16",
|
|
184
|
+
"Category": "Components",
|
|
185
|
+
"Guideline": "Use composition over inheritance",
|
|
186
|
+
"Description": "Compose components using children and props",
|
|
187
|
+
"Do": "Use children prop for flexibility",
|
|
188
|
+
"Don't": "Inheritance hierarchies",
|
|
189
|
+
"Code Good": "<Card>{content}</Card>",
|
|
190
|
+
"Code Bad": "class SpecialCard extends Card",
|
|
191
|
+
"Severity": "Medium",
|
|
192
|
+
"Docs URL": "https://react.dev/learn/thinking-in-react"
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
"No": "17",
|
|
196
|
+
"Category": "Components",
|
|
197
|
+
"Guideline": "Colocate related code",
|
|
198
|
+
"Description": "Keep related components and hooks together",
|
|
199
|
+
"Do": "Related files in same directory",
|
|
200
|
+
"Don't": "Flat structure with many files",
|
|
201
|
+
"Code Good": "components/User/UserCard.tsx",
|
|
202
|
+
"Code Bad": "components/UserCard.tsx + hooks/useUser.ts",
|
|
203
|
+
"Severity": "Low",
|
|
204
|
+
"Docs URL": ""
|
|
205
|
+
},
|
|
206
|
+
{
|
|
207
|
+
"No": "18",
|
|
208
|
+
"Category": "Components",
|
|
209
|
+
"Guideline": "Use fragments to avoid extra DOM",
|
|
210
|
+
"Description": "Fragment or <> for multiple elements without wrapper",
|
|
211
|
+
"Do": "<> for grouping without DOM node",
|
|
212
|
+
"Don't": "Extra div wrappers",
|
|
213
|
+
"Code Good": "<>{items.map(...)}</>",
|
|
214
|
+
"Code Bad": "<div>{items.map(...)}</div>",
|
|
215
|
+
"Severity": "Low",
|
|
216
|
+
"Docs URL": "https://react.dev/reference/react/Fragment"
|
|
217
|
+
},
|
|
218
|
+
{
|
|
219
|
+
"No": "19",
|
|
220
|
+
"Category": "Props",
|
|
221
|
+
"Guideline": "Destructure props",
|
|
222
|
+
"Description": "Destructure props for cleaner component code",
|
|
223
|
+
"Do": "Destructure in function signature",
|
|
224
|
+
"Don't": "props.name props.value throughout",
|
|
225
|
+
"Code Good": "function User({ name, age })",
|
|
226
|
+
"Code Bad": "function User(props)",
|
|
227
|
+
"Severity": "Low",
|
|
228
|
+
"Docs URL": ""
|
|
229
|
+
},
|
|
230
|
+
{
|
|
231
|
+
"No": "20",
|
|
232
|
+
"Category": "Props",
|
|
233
|
+
"Guideline": "Provide default props values",
|
|
234
|
+
"Description": "Use default parameters or defaultProps",
|
|
235
|
+
"Do": "Default values in destructuring",
|
|
236
|
+
"Don't": "Undefined checks throughout",
|
|
237
|
+
"Code Good": "function Button({ size = 'md' })",
|
|
238
|
+
"Code Bad": "if (size === undefined) size = 'md'",
|
|
239
|
+
"Severity": "Low",
|
|
240
|
+
"Docs URL": ""
|
|
241
|
+
},
|
|
242
|
+
{
|
|
243
|
+
"No": "21",
|
|
244
|
+
"Category": "Props",
|
|
245
|
+
"Guideline": "Avoid prop drilling",
|
|
246
|
+
"Description": "Use context or composition for deeply nested data",
|
|
247
|
+
"Do": "Context for global data composition for UI",
|
|
248
|
+
"Don't": "Passing props through 5+ levels",
|
|
249
|
+
"Code Good": "<UserContext.Provider>",
|
|
250
|
+
"Code Bad": "<A user={u}><B user={u}><C user={u}>",
|
|
251
|
+
"Severity": "Medium",
|
|
252
|
+
"Docs URL": "https://react.dev/learn/passing-data-deeply-with-context"
|
|
253
|
+
},
|
|
254
|
+
{
|
|
255
|
+
"No": "22",
|
|
256
|
+
"Category": "Props",
|
|
257
|
+
"Guideline": "Validate props with TypeScript",
|
|
258
|
+
"Description": "Use TypeScript interfaces for prop types",
|
|
259
|
+
"Do": "interface Props { name: string }",
|
|
260
|
+
"Don't": "PropTypes or no validation",
|
|
261
|
+
"Code Good": "interface ButtonProps { onClick: () => void }",
|
|
262
|
+
"Code Bad": "Button.propTypes = {}",
|
|
263
|
+
"Severity": "Medium",
|
|
264
|
+
"Docs URL": ""
|
|
265
|
+
},
|
|
266
|
+
{
|
|
267
|
+
"No": "23",
|
|
268
|
+
"Category": "Events",
|
|
269
|
+
"Guideline": "Use synthetic events correctly",
|
|
270
|
+
"Description": "React normalizes events across browsers",
|
|
271
|
+
"Do": "e.preventDefault() e.stopPropagation()",
|
|
272
|
+
"Don't": "Access native event unnecessarily",
|
|
273
|
+
"Code Good": "onClick={(e) => e.preventDefault()}",
|
|
274
|
+
"Code Bad": "onClick={(e) => e.nativeEvent.preventDefault()}",
|
|
275
|
+
"Severity": "Low",
|
|
276
|
+
"Docs URL": "https://react.dev/reference/react-dom/components/common#react-event-object"
|
|
277
|
+
},
|
|
278
|
+
{
|
|
279
|
+
"No": "24",
|
|
280
|
+
"Category": "Events",
|
|
281
|
+
"Guideline": "Avoid binding in render",
|
|
282
|
+
"Description": "Use arrow functions in class or hooks",
|
|
283
|
+
"Do": "Arrow functions in functional components",
|
|
284
|
+
"Don't": "bind in render or constructor",
|
|
285
|
+
"Code Good": "const handleClick = () => {}",
|
|
286
|
+
"Code Bad": "this.handleClick.bind(this)",
|
|
287
|
+
"Severity": "Medium",
|
|
288
|
+
"Docs URL": ""
|
|
289
|
+
},
|
|
290
|
+
{
|
|
291
|
+
"No": "25",
|
|
292
|
+
"Category": "Events",
|
|
293
|
+
"Guideline": "Pass event handlers not call results",
|
|
294
|
+
"Description": "Pass function reference not invocation",
|
|
295
|
+
"Do": "onClick={handleClick}",
|
|
296
|
+
"Don't": "onClick={handleClick()} causing immediate call",
|
|
297
|
+
"Code Good": "onClick={handleClick}",
|
|
298
|
+
"Code Bad": "onClick={handleClick()}",
|
|
299
|
+
"Severity": "High",
|
|
300
|
+
"Docs URL": ""
|
|
301
|
+
},
|
|
302
|
+
{
|
|
303
|
+
"No": "26",
|
|
304
|
+
"Category": "Forms",
|
|
305
|
+
"Guideline": "Controlled components for forms",
|
|
306
|
+
"Description": "Use state to control form inputs",
|
|
307
|
+
"Do": "value + onChange for inputs",
|
|
308
|
+
"Don't": "Uncontrolled inputs with refs",
|
|
309
|
+
"Code Good": "<input value={val} onChange={setVal}>",
|
|
310
|
+
"Code Bad": "<input ref={inputRef}>",
|
|
311
|
+
"Severity": "Medium",
|
|
312
|
+
"Docs URL": "https://react.dev/reference/react-dom/components/input#controlling-an-input-with-a-state-variable"
|
|
313
|
+
},
|
|
314
|
+
{
|
|
315
|
+
"No": "27",
|
|
316
|
+
"Category": "Forms",
|
|
317
|
+
"Guideline": "Handle form submission properly",
|
|
318
|
+
"Description": "Prevent default and handle in submit handler",
|
|
319
|
+
"Do": "onSubmit with preventDefault",
|
|
320
|
+
"Don't": "onClick on submit button only",
|
|
321
|
+
"Code Good": "<form onSubmit={handleSubmit}>",
|
|
322
|
+
"Code Bad": "<button onClick={handleSubmit}>",
|
|
323
|
+
"Severity": "Medium",
|
|
324
|
+
"Docs URL": ""
|
|
325
|
+
},
|
|
326
|
+
{
|
|
327
|
+
"No": "28",
|
|
328
|
+
"Category": "Forms",
|
|
329
|
+
"Guideline": "Debounce rapid input changes",
|
|
330
|
+
"Description": "Debounce search/filter inputs",
|
|
331
|
+
"Do": "useDeferredValue or debounce for search",
|
|
332
|
+
"Don't": "Filter on every keystroke",
|
|
333
|
+
"Code Good": "useDeferredValue(searchTerm)",
|
|
334
|
+
"Code Bad": "useEffect filtering on every change",
|
|
335
|
+
"Severity": "Medium",
|
|
336
|
+
"Docs URL": "https://react.dev/reference/react/useDeferredValue"
|
|
337
|
+
},
|
|
338
|
+
{
|
|
339
|
+
"No": "29",
|
|
340
|
+
"Category": "Hooks",
|
|
341
|
+
"Guideline": "Follow rules of hooks",
|
|
342
|
+
"Description": "Only call hooks at top level and in React functions",
|
|
343
|
+
"Do": "Hooks at component top level",
|
|
344
|
+
"Don't": "Hooks in conditions loops or callbacks",
|
|
345
|
+
"Code Good": "const [x, setX] = useState()",
|
|
346
|
+
"Code Bad": "if (cond) { const [x, setX] = useState() }",
|
|
347
|
+
"Severity": "High",
|
|
348
|
+
"Docs URL": "https://react.dev/reference/rules/rules-of-hooks"
|
|
349
|
+
},
|
|
350
|
+
{
|
|
351
|
+
"No": "30",
|
|
352
|
+
"Category": "Hooks",
|
|
353
|
+
"Guideline": "Custom hooks for reusable logic",
|
|
354
|
+
"Description": "Extract shared stateful logic to custom hooks",
|
|
355
|
+
"Do": "useCustomHook for reusable patterns",
|
|
356
|
+
"Don't": "Duplicate hook logic across components",
|
|
357
|
+
"Code Good": "const { data } = useFetch(url)",
|
|
358
|
+
"Code Bad": "Duplicate useEffect/useState in components",
|
|
359
|
+
"Severity": "Medium",
|
|
360
|
+
"Docs URL": "https://react.dev/learn/reusing-logic-with-custom-hooks"
|
|
361
|
+
},
|
|
362
|
+
{
|
|
363
|
+
"No": "31",
|
|
364
|
+
"Category": "Hooks",
|
|
365
|
+
"Guideline": "Name custom hooks with use prefix",
|
|
366
|
+
"Description": "Custom hooks must start with use",
|
|
367
|
+
"Do": "useFetch useForm useAuth",
|
|
368
|
+
"Don't": "fetchData or getData for hook",
|
|
369
|
+
"Code Good": "function useFetch(url)",
|
|
370
|
+
"Code Bad": "function fetchData(url)",
|
|
371
|
+
"Severity": "High",
|
|
372
|
+
"Docs URL": ""
|
|
373
|
+
},
|
|
374
|
+
{
|
|
375
|
+
"No": "32",
|
|
376
|
+
"Category": "Context",
|
|
377
|
+
"Guideline": "Use context for global data",
|
|
378
|
+
"Description": "Context for theme auth locale",
|
|
379
|
+
"Do": "Context for app-wide state",
|
|
380
|
+
"Don't": "Context for frequently changing data",
|
|
381
|
+
"Code Good": "<ThemeContext.Provider>",
|
|
382
|
+
"Code Bad": "Context for form field values",
|
|
383
|
+
"Severity": "Medium",
|
|
384
|
+
"Docs URL": "https://react.dev/learn/passing-data-deeply-with-context"
|
|
385
|
+
},
|
|
386
|
+
{
|
|
387
|
+
"No": "33",
|
|
388
|
+
"Category": "Context",
|
|
389
|
+
"Guideline": "Split contexts by concern",
|
|
390
|
+
"Description": "Separate contexts for different domains",
|
|
391
|
+
"Do": "ThemeContext + AuthContext",
|
|
392
|
+
"Don't": "One giant AppContext",
|
|
393
|
+
"Code Good": "<ThemeProvider><AuthProvider>",
|
|
394
|
+
"Code Bad": "<AppProvider value={{theme user...}}>",
|
|
395
|
+
"Severity": "Medium",
|
|
396
|
+
"Docs URL": ""
|
|
397
|
+
},
|
|
398
|
+
{
|
|
399
|
+
"No": "34",
|
|
400
|
+
"Category": "Context",
|
|
401
|
+
"Guideline": "Memoize context values",
|
|
402
|
+
"Description": "Prevent unnecessary re-renders with useMemo",
|
|
403
|
+
"Do": "useMemo for context value object",
|
|
404
|
+
"Don't": "New object reference every render",
|
|
405
|
+
"Code Good": "value={useMemo(() => ({...}), [])}",
|
|
406
|
+
"Code Bad": "value={{ user, theme }}",
|
|
407
|
+
"Severity": "High",
|
|
408
|
+
"Docs URL": ""
|
|
409
|
+
},
|
|
410
|
+
{
|
|
411
|
+
"No": "35",
|
|
412
|
+
"Category": "Performance",
|
|
413
|
+
"Guideline": "Use React DevTools Profiler",
|
|
414
|
+
"Description": "Profile to identify performance bottlenecks",
|
|
415
|
+
"Do": "Profile before optimizing",
|
|
416
|
+
"Don't": "Optimize without measuring",
|
|
417
|
+
"Code Good": "React DevTools Profiler",
|
|
418
|
+
"Code Bad": "Guessing at bottlenecks",
|
|
419
|
+
"Severity": "Medium",
|
|
420
|
+
"Docs URL": "https://react.dev/learn/react-developer-tools"
|
|
421
|
+
},
|
|
422
|
+
{
|
|
423
|
+
"No": "36",
|
|
424
|
+
"Category": "Performance",
|
|
425
|
+
"Guideline": "Lazy load components",
|
|
426
|
+
"Description": "Use React.lazy for code splitting",
|
|
427
|
+
"Do": "lazy() for routes and heavy components",
|
|
428
|
+
"Don't": "Import everything upfront",
|
|
429
|
+
"Code Good": "const Page = lazy(() => import('./Page'))",
|
|
430
|
+
"Code Bad": "import Page from './Page'",
|
|
431
|
+
"Severity": "Medium",
|
|
432
|
+
"Docs URL": "https://react.dev/reference/react/lazy"
|
|
433
|
+
},
|
|
434
|
+
{
|
|
435
|
+
"No": "37",
|
|
436
|
+
"Category": "Performance",
|
|
437
|
+
"Guideline": "Virtualize long lists",
|
|
438
|
+
"Description": "Use windowing for lists over 100 items",
|
|
439
|
+
"Do": "react-window or react-virtual",
|
|
440
|
+
"Don't": "Render thousands of DOM nodes",
|
|
441
|
+
"Code Good": "<VirtualizedList items={items}/>",
|
|
442
|
+
"Code Bad": "{items.map(i => <Item />)}",
|
|
443
|
+
"Severity": "High",
|
|
444
|
+
"Docs URL": ""
|
|
445
|
+
},
|
|
446
|
+
{
|
|
447
|
+
"No": "38",
|
|
448
|
+
"Category": "Performance",
|
|
449
|
+
"Guideline": "Batch state updates",
|
|
450
|
+
"Description": "React 18 auto-batches but be aware",
|
|
451
|
+
"Do": "Let React batch related updates",
|
|
452
|
+
"Don't": "Manual batching with flushSync",
|
|
453
|
+
"Code Good": "setA(1); setB(2); // batched",
|
|
454
|
+
"Code Bad": "flushSync(() => setA(1))",
|
|
455
|
+
"Severity": "Low",
|
|
456
|
+
"Docs URL": "https://react.dev/learn/queueing-a-series-of-state-updates"
|
|
457
|
+
},
|
|
458
|
+
{
|
|
459
|
+
"No": "39",
|
|
460
|
+
"Category": "ErrorHandling",
|
|
461
|
+
"Guideline": "Use error boundaries",
|
|
462
|
+
"Description": "Catch JavaScript errors in component tree",
|
|
463
|
+
"Do": "ErrorBoundary wrapping sections",
|
|
464
|
+
"Don't": "Let errors crash entire app",
|
|
465
|
+
"Code Good": "<ErrorBoundary><App/></ErrorBoundary>",
|
|
466
|
+
"Code Bad": "No error handling",
|
|
467
|
+
"Severity": "High",
|
|
468
|
+
"Docs URL": "https://react.dev/reference/react/Component#catching-rendering-errors-with-an-error-boundary"
|
|
469
|
+
},
|
|
470
|
+
{
|
|
471
|
+
"No": "40",
|
|
472
|
+
"Category": "ErrorHandling",
|
|
473
|
+
"Guideline": "Handle async errors",
|
|
474
|
+
"Description": "Catch errors in async operations",
|
|
475
|
+
"Do": "try/catch in async handlers",
|
|
476
|
+
"Don't": "Unhandled promise rejections",
|
|
477
|
+
"Code Good": "try { await fetch() } catch(e) {}",
|
|
478
|
+
"Code Bad": "await fetch() // no catch",
|
|
479
|
+
"Severity": "High",
|
|
480
|
+
"Docs URL": ""
|
|
481
|
+
},
|
|
482
|
+
{
|
|
483
|
+
"No": "41",
|
|
484
|
+
"Category": "Testing",
|
|
485
|
+
"Guideline": "Test behavior not implementation",
|
|
486
|
+
"Description": "Test what user sees and does",
|
|
487
|
+
"Do": "Test renders and interactions",
|
|
488
|
+
"Don't": "Test internal state or methods",
|
|
489
|
+
"Code Good": "expect(screen.getByText('Hello'))",
|
|
490
|
+
"Code Bad": "expect(component.state.name)",
|
|
491
|
+
"Severity": "Medium",
|
|
492
|
+
"Docs URL": "https://testing-library.com/docs/react-testing-library/intro/"
|
|
493
|
+
},
|
|
494
|
+
{
|
|
495
|
+
"No": "42",
|
|
496
|
+
"Category": "Testing",
|
|
497
|
+
"Guideline": "Use testing-library queries",
|
|
498
|
+
"Description": "Use accessible queries",
|
|
499
|
+
"Do": "getByRole getByLabelText",
|
|
500
|
+
"Don't": "getByTestId for everything",
|
|
501
|
+
"Code Good": "getByRole('button')",
|
|
502
|
+
"Code Bad": "getByTestId('submit-btn')",
|
|
503
|
+
"Severity": "Medium",
|
|
504
|
+
"Docs URL": "https://testing-library.com/docs/queries/about#priority"
|
|
505
|
+
},
|
|
506
|
+
{
|
|
507
|
+
"No": "43",
|
|
508
|
+
"Category": "Accessibility",
|
|
509
|
+
"Guideline": "Use semantic HTML",
|
|
510
|
+
"Description": "Proper HTML elements for their purpose",
|
|
511
|
+
"Do": "button for clicks nav for navigation",
|
|
512
|
+
"Don't": "div with onClick for buttons",
|
|
513
|
+
"Code Good": "<button onClick={...}>",
|
|
514
|
+
"Code Bad": "<div onClick={...}>",
|
|
515
|
+
"Severity": "High",
|
|
516
|
+
"Docs URL": "https://react.dev/reference/react-dom/components#all-html-components"
|
|
517
|
+
},
|
|
518
|
+
{
|
|
519
|
+
"No": "44",
|
|
520
|
+
"Category": "Accessibility",
|
|
521
|
+
"Guideline": "Manage focus properly",
|
|
522
|
+
"Description": "Handle focus for modals dialogs",
|
|
523
|
+
"Do": "Focus trap in modals return focus on close",
|
|
524
|
+
"Don't": "No focus management",
|
|
525
|
+
"Code Good": "useEffect to focus input",
|
|
526
|
+
"Code Bad": "Modal without focus trap",
|
|
527
|
+
"Severity": "High",
|
|
528
|
+
"Docs URL": ""
|
|
529
|
+
}
|
|
530
|
+
]
|