-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathreact.yaml
More file actions
203 lines (175 loc) · 9.4 KB
/
react.yaml
File metadata and controls
203 lines (175 loc) · 9.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
# React Code Review Guidelines
# Comprehensive rules for React performance, state management, and best practices
description: React best practices covering performance optimization, state management, effects, component design, hooks, and common pitfalls
globs:
- "**/*.jsx"
- "**/*.tsx"
- "**/components/**/*.js"
- "**/components/**/*.ts"
- "**/*Component*"
- "**/*Hook*"
rules:
# Performance Rules
- name: use-memo-appropriately
description: >
Use useMemo for expensive computations that don't need to run on every render.
Don't overuse - memoization has overhead. Memoize when: computation is expensive,
result is referentially stable for child components, or in context providers.
Profile before adding useMemo to verify performance benefit.
severity: medium
- name: use-callback-for-stable-references
description: >
Use useCallback for functions passed to memoized children or used in dependency
arrays. Prevents unnecessary re-renders of memoized components. Don't wrap every
function - only those causing re-render issues. Include all used values in dependencies.
severity: medium
- name: use-react-memo-selectively
description: >
Wrap components in React.memo() when they re-render often with same props.
Effective for components receiving complex props from frequently updating parents.
Don't wrap everything - memo comparison has cost. Profile to verify benefit.
Use custom comparison function for complex props.
severity: medium
- name: implement-virtualization
description: >
Use virtualization (react-window, react-virtualized, @tanstack/virtual) for long lists.
Only render visible items plus buffer. Essential for lists with hundreds+ items.
Improves initial render and memory usage. Consider item height estimation strategy.
severity: high
- name: avoid-inline-objects-and-functions
description: >
Avoid creating new objects, arrays, or functions inline in JSX props. Each render
creates new references, breaking memo comparisons. Move to useMemo/useCallback or
define outside component. Exception: simple leaf components that don't memo.
severity: medium
# State Management Rules
- name: prefer-local-state
description: >
Keep state as local as possible - lift only when needed. Not everything needs global
state. Local state is simpler, more performant, and easier to reason about.
Lift state when siblings need to share it. Use composition over context for prop drilling.
severity: medium
- name: use-context-appropriately
description: >
Use Context for truly global data (theme, user, locale) that changes infrequently.
Context changes re-render all consumers. For frequently changing data, consider
state management libraries or split contexts. Memoize context value objects.
severity: high
- name: derive-state-dont-sync
description: >
Derive computed values during render instead of syncing state with useEffect.
Derived state is simpler and always consistent. Use useMemo if derivation is expensive.
Don't store values that can be computed from props or other state.
severity: high
- name: batch-state-updates
description: >
React 18+ batches state updates automatically. For React 17, multiple setState calls
in event handlers are batched, but not in async callbacks. Use functional updates
when new state depends on previous. Understand batching behavior for your React version.
severity: medium
# Effects Rules
- name: specify-effect-dependencies-correctly
description: >
Include all values from component scope used in useEffect in the dependency array.
Missing dependencies cause stale closure bugs. Use ESLint exhaustive-deps rule.
If a dependency changes too often, consider restructuring, not removing the dependency.
severity: critical
- name: cleanup-effects-properly
description: >
Return cleanup function from useEffect for subscriptions, timers, and listeners.
Cleanup runs before next effect and on unmount. Prevents memory leaks and stale
handlers. Handle async operations with AbortController or isMounted flags.
severity: high
- name: handle-effect-race-conditions
description: >
Handle race conditions in async effects - earlier requests may complete after later ones.
Use AbortController to cancel superseded requests. Or use cleanup with boolean flag.
Consider libraries like react-query or SWR that handle this automatically.
severity: high
- name: avoid-effects-for-transformations
description: >
Don't use effects for data transformation or computation. Effects are for synchronizing
with external systems, not for internal state transformations. Use direct computation
during render or useMemo. Effects for transformations cause extra renders.
severity: medium
# Component Design Rules
- name: prefer-composition-over-inheritance
description: >
Use composition via props.children and render props instead of inheritance. Compose
smaller components into larger ones. Specialization through props not subclasses.
React doesn't use class inheritance for component reuse. Extract shared logic to hooks.
severity: medium
- name: solve-prop-drilling-appropriately
description: >
Address prop drilling based on severity: shallow drilling is fine, deep drilling
consider context or composition. Use compound components pattern. Don't reach for
global state too early. Context is for widely-shared data, not all prop drilling.
severity: medium
- name: use-render-props-and-children-as-function
description: >
Use render props for cross-cutting concerns and inversion of control. Pass render
function as prop or children. Useful for headless UI components. Consider hooks as
modern alternative for logic sharing. Render props still useful for render control.
severity: low
- name: keep-components-focused
description: >
Components should do one thing well. Extract subcomponents when components grow.
Separate container (logic) and presentational (UI) concerns where helpful. Balance
between too many tiny components and monolithic components. Components should be readable.
severity: medium
# Hooks Rules
- name: follow-rules-of-hooks
description: >
Only call hooks at the top level, never inside loops, conditions, or nested functions.
Only call hooks from React functions. These rules ensure hooks are called in same order
every render. Use eslint-plugin-react-hooks to enforce. Violations cause subtle bugs.
severity: critical
- name: extract-custom-hooks
description: >
Extract reusable logic into custom hooks (useXxx naming convention). Custom hooks
compose built-in hooks. Each custom hook should do one thing. Hooks are the primary
code reuse mechanism in React. Test custom hooks with @testing-library/react-hooks.
severity: medium
- name: handle-hook-dependencies-correctly
description: >
All hooks with dependency arrays (useEffect, useMemo, useCallback) must include all
dependencies. Missing deps cause stale values. Functions as deps often need useCallback.
Objects may need useMemo or stable references. Trust the exhaustive-deps lint rule.
severity: high
# Common Pitfalls Rules
- name: avoid-stale-closures
description: >
Closures in React can capture stale values when not properly handled. Common in
effects and callbacks. Include all dependencies in arrays. Use functional updates
for setState depending on previous value. Understand when values are captured.
severity: high
- name: prevent-infinite-loops
description: >
Avoid infinite re-render loops: don't setState unconditionally in effects, don't
update state that's in effect dependencies, ensure stable dependency references.
Effects running continuously is a sign of dependency or state update issues.
severity: critical
- name: use-key-prop-correctly
description: >
Always provide stable, unique key prop for list items. Keys help React identify which
items changed. Using index as key causes bugs with reordering and stateful children.
Use unique IDs from data. Keys must be unique among siblings, not globally.
severity: high
- name: avoid-object-identity-problems
description: >
Objects and arrays created inline have new identity each render, breaking memo
comparisons. Move static objects outside component, use useMemo for computed objects,
or memoize components that receive object props. Profile to verify actual issues.
severity: medium
- name: handle-conditional-hooks-correctly
description: >
Never call hooks conditionally as it breaks hook ordering. Instead, call hook always
and handle condition inside or in consuming code. For conditional effects, run effect
always but conditionally execute logic inside. Early return before hooks is prohibited.
severity: critical
- name: manage-form-state-properly
description: >
Choose controlled vs uncontrolled forms based on needs. Controlled for complex validation,
dependent fields, or submission logic. Uncontrolled for simple forms or performance.
Consider form libraries (react-hook-form, formik) for complex forms. Don't mix approaches.
severity: medium