react-state-basis 0.3.3 β 0.4.0
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 +335 -113
- package/dist/index.js +142 -132
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +142 -132
- package/dist/index.mjs.map +1 -1
- package/package.json +10 -10
package/README.md
CHANGED
|
@@ -5,212 +5,434 @@
|
|
|
5
5
|
<div align="center">
|
|
6
6
|
|
|
7
7
|
# π react-state-basis
|
|
8
|
-
###
|
|
8
|
+
### Runtime state profiler for React
|
|
9
9
|
|
|
10
10
|
[](https://www.npmjs.com/package/react-state-basis)
|
|
11
11
|
[](https://github.com/liovic/react-state-basis/stargazers)
|
|
12
12
|
[](https://opensource.org/licenses/MIT)
|
|
13
13
|
|
|
14
|
-
**
|
|
14
|
+
**Catches redundant state and update chains using temporal cross-correlation.**
|
|
15
15
|
|
|
16
16
|
</div>
|
|
17
17
|
|
|
18
18
|
---
|
|
19
19
|
|
|
20
|
-
## What
|
|
20
|
+
## What Does It Do?
|
|
21
21
|
|
|
22
|
-
**react-state-basis**
|
|
22
|
+
**react-state-basis** watches your React app in development and flags common architectural issues:
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
- **Redundant state** - Two states that always update together
|
|
25
|
+
- **Update chains** - Effects that trigger more state updates (double renders)
|
|
26
|
+
- **Infinite loops** - Circular dependencies that freeze your browser
|
|
27
|
+
- **Tight coupling** - State variables that should be independent but aren't
|
|
25
28
|
|
|
26
|
-
|
|
27
|
-
> It is not a state manager and not a replacement for React DevTools.
|
|
29
|
+
It works by tracking *when* state updates happen (temporal patterns), not *what* the values are.
|
|
28
30
|
|
|
29
31
|
---
|
|
30
32
|
|
|
31
|
-
##
|
|
33
|
+
## Quick Example
|
|
34
|
+
```tsx
|
|
35
|
+
// β Basis will flag this
|
|
36
|
+
const [user, setUser] = useState(null);
|
|
37
|
+
const [isLoggedIn, setIsLoggedIn] = useState(false);
|
|
32
38
|
|
|
33
|
-
|
|
39
|
+
useEffect(() => {
|
|
40
|
+
setIsLoggedIn(!!user); // Double render - flagged as sync leak
|
|
41
|
+
}, [user]);
|
|
34
42
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
43
|
+
// β
Better
|
|
44
|
+
const [user, setUser] = useState(null);
|
|
45
|
+
const isLoggedIn = !!user; // Computed, no second render
|
|
46
|
+
```
|
|
39
47
|
|
|
40
|
-
|
|
48
|
+
---
|
|
41
49
|
|
|
42
|
-
|
|
50
|
+
## See It Work
|
|
51
|
+
|
|
52
|
+
The optional HUD shows your state basis matrix in real-time:
|
|
53
|
+
|
|
54
|
+
<p align="center">
|
|
55
|
+
<img src="./assets/react-state-basis.gif" width="800" alt="React State Basis Demo" />
|
|
56
|
+
</p>
|
|
43
57
|
|
|
44
58
|
---
|
|
45
59
|
|
|
46
|
-
##
|
|
60
|
+
## Real-World Audits
|
|
47
61
|
|
|
48
|
-
-
|
|
49
|
-
A real-time visualization of state activity. If rows pulse together, the architecture is coupled or redundant.
|
|
62
|
+
Basis has been tested on major open-source projects to validate detection accuracy:
|
|
50
63
|
|
|
51
|
-
|
|
52
|
-
|
|
64
|
+
### Excalidraw (114k+ β)
|
|
65
|
+
**Detected:** Causal Sync Leak in theme state synchronization
|
|
66
|
+
**Issue:** A `useEffect` was manually syncing theme state, causing an unnecessary double render on every theme toggle
|
|
67
|
+
**Fix:** [PR #10637](https://github.com/excalidraw/excalidraw/pull/10637) - Replaced with a computed value
|
|
53
68
|
|
|
54
|
-
|
|
55
|
-
|
|
69
|
+
<p align="center">
|
|
70
|
+
<img src="./assets/excalidraw-audit.png" width="800" alt="Excalidraw Audit" />
|
|
71
|
+
</p>
|
|
56
72
|
|
|
57
|
-
-
|
|
58
|
-
|
|
73
|
+
### shadcn-admin (10k+ β)
|
|
74
|
+
**Detected:** Redundant state pattern in mobile detection hooks
|
|
75
|
+
**Issue:** Viewport resize events were being synchronized via effects rather than direct subscriptions
|
|
76
|
+
**Fix:** [PR #274](https://github.com/satnaing/shadcn-admin/pull/274) - Optimized subscription pattern
|
|
59
77
|
|
|
60
|
-
|
|
61
|
-
|
|
78
|
+
<p align="center">
|
|
79
|
+
<img src="./assets/shadcn-admin.png" width="800" alt="shadcn Admin Audit" />
|
|
80
|
+
</p>
|
|
81
|
+
|
|
82
|
+
> **Note:** These are proposed architectural improvements. Basis points out patterns worth investigating - the final decision rests with the maintainer.
|
|
62
83
|
|
|
63
84
|
---
|
|
64
85
|
|
|
65
|
-
##
|
|
86
|
+
## Setup (Vite)
|
|
66
87
|
|
|
67
|
-
###
|
|
68
|
-
|
|
88
|
+
### 1. Install
|
|
89
|
+
```bash
|
|
90
|
+
npm i react-state-basis
|
|
91
|
+
```
|
|
69
92
|
|
|
93
|
+
### 2. Add to `vite.config.ts`
|
|
70
94
|
```tsx
|
|
71
|
-
|
|
95
|
+
import { defineConfig } from 'vite';
|
|
96
|
+
import react from '@vitejs/plugin-react';
|
|
97
|
+
import { basis } from 'react-state-basis/vite';
|
|
98
|
+
|
|
99
|
+
export default defineConfig({
|
|
100
|
+
plugins: [
|
|
101
|
+
react({
|
|
102
|
+
babel: { plugins: [['react-state-basis/plugin']] }
|
|
103
|
+
}),
|
|
104
|
+
basis()
|
|
105
|
+
]
|
|
106
|
+
});
|
|
72
107
|
```
|
|
73
108
|
|
|
74
|
-
|
|
109
|
+
### 3. Wrap your app
|
|
110
|
+
```tsx
|
|
111
|
+
import { BasisProvider } from 'react-state-basis';
|
|
75
112
|
|
|
76
|
-
|
|
113
|
+
root.render(
|
|
114
|
+
<BasisProvider debug={true}>
|
|
115
|
+
<App />
|
|
116
|
+
</BasisProvider>
|
|
117
|
+
);
|
|
118
|
+
```
|
|
77
119
|
|
|
78
|
-
|
|
120
|
+
### 4. Verify It's Working
|
|
79
121
|
|
|
80
|
-
|
|
122
|
+
Add this test pattern to any component:
|
|
123
|
+
```tsx
|
|
124
|
+
const [a, setA] = useState(0);
|
|
125
|
+
const [b, setB] = useState(0);
|
|
81
126
|
|
|
82
|
-
|
|
83
|
-
|
|
127
|
+
useEffect(() => {
|
|
128
|
+
setB(a); // Basis will flag this
|
|
129
|
+
}, [a]);
|
|
130
|
+
```
|
|
84
131
|
|
|
85
|
-
|
|
86
|
-
> βHow does this state behave relative to other states over time?β
|
|
132
|
+
Trigger an update (e.g., click a button that calls `setA(1)`). You should see a console alert within ~100ms.
|
|
87
133
|
|
|
88
|
-
|
|
134
|
+
---
|
|
89
135
|
|
|
90
|
-
|
|
91
|
-
The tool is designed to be **used**, not configured.
|
|
136
|
+
## What You'll See
|
|
92
137
|
|
|
93
|
-
|
|
138
|
+
### Console Alerts
|
|
94
139
|
|
|
95
|
-
|
|
140
|
+
**Redundant Pattern:**
|
|
141
|
+
Detected when two variables move in perfect unison.
|
|
142
|
+
```
|
|
143
|
+
π BASIS | REDUNDANT PATTERN
|
|
144
|
+
π Location: TodoList.tsx
|
|
145
|
+
Observation: "todos" and "count" move together.
|
|
146
|
+
One is likely a direct mirror of the other. Confidence: 94%
|
|
147
|
+
Action: Refactor "count" to useMemo.
|
|
148
|
+
```
|
|
96
149
|
|
|
97
|
-
|
|
150
|
+
**Sync Leak (Causal Chain):**
|
|
151
|
+
Detected when one variable consistently triggers another with a temporal lag.
|
|
152
|
+
```
|
|
153
|
+
π‘ BASIS | DETECTED SYNC LEAK
|
|
154
|
+
π Location: AuthProvider.tsx
|
|
155
|
+
Flow: user β Effect β isLoggedIn
|
|
156
|
+
Context: The engine detected a consistent 20ms lag between these updates.
|
|
157
|
+
Result: This creates a Double Render Cycle.
|
|
158
|
+
```
|
|
98
159
|
|
|
99
|
-
|
|
160
|
+
**Infinite Loop:**
|
|
161
|
+
Detected when a variable updates too rapidly (circuit breaker).
|
|
162
|
+
```
|
|
163
|
+
π BASIS CRITICAL | CIRCUIT BREAKER
|
|
164
|
+
Infinite oscillation detected on: "counter"
|
|
165
|
+
Execution halted to prevent browser thread lock.
|
|
166
|
+
```
|
|
100
167
|
|
|
101
|
-
|
|
168
|
+
### Health Report
|
|
102
169
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
170
|
+
Check your entire app's state architecture:
|
|
171
|
+
```tsx
|
|
172
|
+
window.printBasisReport();
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
Shows:
|
|
176
|
+
- **Health Score** - Percentage of independent vs. synchronized state
|
|
177
|
+
- **Synchronized Clusters** - Groups of variables that move together
|
|
178
|
+
- **Correlation Matrix** - Full pairwise similarity analysis (for <15 variables)
|
|
106
179
|
|
|
107
180
|
---
|
|
108
181
|
|
|
109
|
-
##
|
|
182
|
+
## How It Works (v0.4.0)
|
|
110
183
|
|
|
111
|
-
|
|
184
|
+
### Temporal Cross-Correlation
|
|
185
|
+
|
|
186
|
+
Basis tracks **when** state updates occur, creating a 50-tick timeline for each variable:
|
|
187
|
+
```
|
|
188
|
+
useState("count"): [0,0,1,0,0,1,1,0,...] (updates at ticks 2, 5, 6)
|
|
189
|
+
useState("total"): [0,0,1,0,0,1,1,0,...] (same pattern)
|
|
190
|
+
β Redundant: identical temporal signature
|
|
191
|
+
```
|
|
112
192
|
|
|
113
|
-
|
|
193
|
+
For every pair of variables, Basis checks three temporal relationships:
|
|
114
194
|
|
|
115
|
-
|
|
116
|
-
```bash
|
|
117
|
-
npm i react-state-basis
|
|
195
|
+
1. **Synchronous (Redundancy):** Do they update in the same tick?
|
|
118
196
|
```
|
|
197
|
+
A: [0,1,0,1,0,...]
|
|
198
|
+
B: [0,1,0,1,0,...] β Flagged as redundant
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
2. **Lead-Lag (A β B):** Does B consistently follow A in the next tick?
|
|
202
|
+
```
|
|
203
|
+
A: [0,1,0,1,0,...]
|
|
204
|
+
B: [0,0,1,0,1,...] β B follows A (sync leak detected)
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
3. **Lead-Lag (B β A):** Does A consistently follow B?
|
|
208
|
+
```
|
|
209
|
+
A: [0,0,1,0,1,...]
|
|
210
|
+
B: [0,1,0,1,0,...] β A follows B (reverse causality)
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
The engine uses **offset-based comparison** to check these patterns without allocating temporary arrays, ensuring minimal overhead even at high frame rates.
|
|
119
214
|
|
|
120
|
-
###
|
|
215
|
+
### Performance Optimizations
|
|
121
216
|
|
|
122
|
-
|
|
123
|
-
|
|
217
|
+
- **Idle Filtering:** Only analyzes variables with 2+ updates, reducing pairwise comparisons by ~90% in typical applications (measured on Excalidraw's 47-hook codebase)
|
|
218
|
+
- **Batched Analysis:** Runs every 5 ticks (~100ms) to avoid impacting frame budget
|
|
219
|
+
- **Console Throttling:** Same alert won't repeat within 5 seconds
|
|
220
|
+
- **Zero Production Overhead:** Entire library is replaced with no-op shims in production builds
|
|
124
221
|
|
|
222
|
+
### What Gets Flagged?
|
|
223
|
+
|
|
224
|
+
**Redundant Pattern Example:**
|
|
125
225
|
```tsx
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
226
|
+
// β Before (Basis flags this)
|
|
227
|
+
const [count, setCount] = useState(0);
|
|
228
|
+
const [doubled, setDoubled] = useState(0);
|
|
129
229
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
});
|
|
230
|
+
useEffect(() => {
|
|
231
|
+
setDoubled(count * 2);
|
|
232
|
+
}, [count]);
|
|
233
|
+
|
|
234
|
+
// β
After (Basis suggestion)
|
|
235
|
+
const [count, setCount] = useState(0);
|
|
236
|
+
const doubled = useMemo(() => count * 2, [count]);
|
|
138
237
|
```
|
|
139
238
|
|
|
140
|
-
|
|
239
|
+
**Sync Leak Example:**
|
|
240
|
+
```tsx
|
|
241
|
+
// β Before (causes double render)
|
|
242
|
+
const [user, setUser] = useState(null);
|
|
243
|
+
const [isLoggedIn, setIsLoggedIn] = useState(false);
|
|
141
244
|
|
|
142
|
-
|
|
245
|
+
useEffect(() => {
|
|
246
|
+
setIsLoggedIn(!!user);
|
|
247
|
+
}, [user]);
|
|
143
248
|
|
|
144
|
-
|
|
145
|
-
|
|
249
|
+
// β
After (single render)
|
|
250
|
+
const [user, setUser] = useState(null);
|
|
251
|
+
const isLoggedIn = !!user; // Derived, no effect needed
|
|
252
|
+
```
|
|
146
253
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
254
|
+
---
|
|
255
|
+
|
|
256
|
+
## Upgrading from v0.3.x
|
|
257
|
+
|
|
258
|
+
### Breaking Changes
|
|
259
|
+
None! v0.4.0 is a drop-in replacement.
|
|
260
|
+
|
|
261
|
+
### What's Different
|
|
262
|
+
- **Better Detection:** Temporal analysis reduces false positives by distinguishing redundancy from causality
|
|
263
|
+
- **New Alert Type:** "DETECTED SYNC LEAK" identifies effect-driven update chains with directional insight
|
|
264
|
+
- **Console Throttling:** Same pair won't spam console (5-second cooldown between identical alerts)
|
|
265
|
+
- **Idle Filtering:** Variables that haven't updated are excluded from analysis
|
|
266
|
+
|
|
267
|
+
### Action Required
|
|
268
|
+
None. Just update the package and restart your dev server.
|
|
269
|
+
```bash
|
|
270
|
+
npm update react-state-basis
|
|
152
271
|
```
|
|
153
272
|
|
|
154
|
-
|
|
273
|
+
---
|
|
274
|
+
|
|
275
|
+
## Production Safety
|
|
276
|
+
|
|
277
|
+
In production builds, the entire tool is replaced with zero-op shims. **Zero runtime overhead. Zero bundle size increase.**
|
|
278
|
+
```json
|
|
279
|
+
// package.json - automatic based on NODE_ENV
|
|
280
|
+
"exports": {
|
|
281
|
+
".": {
|
|
282
|
+
"development": "./dist/index.mjs",
|
|
283
|
+
"production": "./dist/production.mjs", // No-op shims
|
|
284
|
+
"default": "./dist/production.mjs"
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
```
|
|
155
288
|
|
|
156
|
-
|
|
289
|
+
---
|
|
157
290
|
|
|
158
|
-
|
|
291
|
+
## When to Skip Files
|
|
159
292
|
|
|
293
|
+
Add `// @basis-ignore` at the top of a file to disable instrumentation:
|
|
160
294
|
```tsx
|
|
161
295
|
// @basis-ignore
|
|
296
|
+
// This file uses high-frequency animations and intentional state synchronization
|
|
162
297
|
```
|
|
163
298
|
|
|
164
|
-
|
|
299
|
+
**Good candidates for skipping:**
|
|
300
|
+
- **High-frequency animations** (>60fps state updates)
|
|
301
|
+
- **WebSocket message handlers** (rapid, intentional updates)
|
|
302
|
+
- **Canvas/WebGL render loops** (performance-critical paths)
|
|
303
|
+
- **Intentional synchronization** (e.g., React Query β local cache mirrors)
|
|
304
|
+
- **Third-party library wrappers** (where you don't control the architecture)
|
|
305
|
+
|
|
306
|
+
---
|
|
307
|
+
|
|
308
|
+
## Comparison to Other Tools
|
|
309
|
+
|
|
310
|
+
| Tool | Focus | When to Use |
|
|
311
|
+
|------|-------|-------------|
|
|
312
|
+
| **React DevTools** | Component hierarchy & values | Debugging specific components |
|
|
313
|
+
| **Why Did You Render** | Re-render optimization | Performance tuning renders |
|
|
314
|
+
| **ESLint exhaustive-deps** | Static dependency analysis | Preventing missing deps |
|
|
315
|
+
| **react-state-basis** | **Temporal state relationships** | **Finding redundant state & effect chains** |
|
|
316
|
+
|
|
317
|
+
These tools are complementary - use them together for best results.
|
|
165
318
|
|
|
166
319
|
---
|
|
167
320
|
|
|
168
|
-
##
|
|
321
|
+
## Performance Impact (Measured)
|
|
322
|
+
|
|
323
|
+
**Development Mode**
|
|
324
|
+
|
|
325
|
+
These measurements were taken using the built-in **Stress Lab** with 100 active hooks and continuous state updates, observed in Chrome DevTools Performance and Web Vitals panels.
|
|
169
326
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
327
|
+
Location: `/example`
|
|
328
|
+
|
|
329
|
+
**Observed impact:**
|
|
330
|
+
|
|
331
|
+
* **Per state update overhead:** ~0.3ms (lightweight hook instrumentation)
|
|
332
|
+
* **Analysis pass (every ~100ms / 5 ticks):** ~2β4ms in typical applications
|
|
333
|
+
* **Frame budget impact:** <1% when idle, ~5β10% during active stress testing
|
|
334
|
+
* **Render path safety:** Analysis runs asynchronously, outside of Reactβs render cycle
|
|
335
|
+
|
|
336
|
+
> Results will vary by hardware, browser, and workload. Use the Stress Lab to reproduce and compare Basis ON vs OFF in your own environment.
|
|
337
|
+
|
|
338
|
+
<p align="center">
|
|
339
|
+
<img src="./assets/performance-test.png" width="800" alt="shadcn Admin Audit" />
|
|
340
|
+
</p>
|
|
341
|
+
|
|
342
|
+
|
|
343
|
+
**Production Mode:**
|
|
344
|
+
- Overhead: ~0.01ms per hook call (negligible wrapper overhead)
|
|
345
|
+
- Bundle size: ~2-3 KB minified (no-op wrappers only, no analysis engine)
|
|
346
|
+
- Monitoring logic: 100% removed
|
|
347
|
+
- HUD component: 100% removed
|
|
177
348
|
|
|
178
349
|
---
|
|
179
350
|
|
|
180
|
-
##
|
|
351
|
+
## Limitations (v0.4.0)
|
|
181
352
|
|
|
182
|
-
|
|
183
|
-
-
|
|
184
|
-
-
|
|
353
|
+
**What works well:**
|
|
354
|
+
- β
Detecting synchronous redundant state
|
|
355
|
+
- β
Flagging effect-driven update chains (A β Effect β B)
|
|
356
|
+
- β
Catching infinite loops before browser freeze
|
|
357
|
+
- β
Distinguishing causality from redundancy
|
|
185
358
|
|
|
359
|
+
**Known edge cases:**
|
|
360
|
+
- β οΈ **Async gaps:** Updates delayed by >40ms (e.g., slow API responses) may appear independent
|
|
361
|
+
- β οΈ **Intentional sync:** Sometimes synchronization is required for library compatibility
|
|
362
|
+
- β οΈ **Complex multi-way dependencies:** Three or more interconnected states might not show full relationship graph
|
|
363
|
+
- β οΈ **Requires judgment:** Tool points out patterns worth investigating - you decide if they're issues
|
|
186
364
|
|
|
187
|
-
|
|
365
|
+
**False positives can happen.** Always verify before refactoring.
|
|
188
366
|
|
|
189
367
|
---
|
|
190
368
|
|
|
191
369
|
## Roadmap
|
|
192
370
|
|
|
193
|
-
|
|
194
|
-
- [
|
|
195
|
-
- [
|
|
196
|
-
- [
|
|
197
|
-
- [
|
|
198
|
-
|
|
199
|
-
|
|
371
|
+
### v0.5.0 (Planned)
|
|
372
|
+
- [ ] Zustand & Redux middleware integration
|
|
373
|
+
- [ ] Visual dependency graph in HUD
|
|
374
|
+
- [ ] Automated fix suggestions with one-click apply
|
|
375
|
+
- [ ] Historical trend tracking across sessions
|
|
376
|
+
|
|
377
|
+
### Future Ideas
|
|
378
|
+
- [ ] Domain isolation analysis (detect feature boundaries)
|
|
379
|
+
- [ ] Export audit reports for team reviews
|
|
380
|
+
- [ ] CI integration for architectural regressions
|
|
381
|
+
|
|
382
|
+
---
|
|
383
|
+
|
|
384
|
+
## Troubleshooting
|
|
385
|
+
|
|
386
|
+
**"I'm not seeing any alerts"**
|
|
387
|
+
1. Verify `debug={true}` is set in `<BasisProvider>`
|
|
388
|
+
2. Check that the Babel plugin is loaded (restart dev server after config changes)
|
|
389
|
+
3. Create a test pattern (see "Verify It's Working" section)
|
|
390
|
+
4. Open browser console and look for `Basis Auditor | Structural Relationship Check`
|
|
200
391
|
|
|
201
|
-
|
|
202
|
-
-
|
|
203
|
-
-
|
|
204
|
-
-
|
|
205
|
-
- [ ] **Redux Integration:** Connecting the causal engine to Redux dispatch cycles.
|
|
206
|
-
- [ ] **CLI Initializer:** `rsb-init` to automatically configure Babel/Vite plugins.
|
|
207
|
-
- [ ] **Context Auditor:** Tracking signal collisions across multiple React Context providers.
|
|
392
|
+
**"Too many alerts"**
|
|
393
|
+
- Use `// @basis-ignore` for animation-heavy files
|
|
394
|
+
- Check if your app has intentional state synchronization patterns
|
|
395
|
+
- Consider if alerts are revealing actual architectural issues
|
|
208
396
|
|
|
209
|
-
|
|
210
|
-
-
|
|
211
|
-
-
|
|
397
|
+
**"Alert says 'sync leak' but I need that effect"**
|
|
398
|
+
- Some effects are necessary (e.g., syncing to localStorage)
|
|
399
|
+
- Basis flags patterns, not bugs - use your judgment
|
|
400
|
+
- If it's intentional, add a comment explaining why
|
|
212
401
|
|
|
213
402
|
---
|
|
214
403
|
|
|
404
|
+
## FAQ
|
|
405
|
+
|
|
406
|
+
**Q: Will this slow down my app?**
|
|
407
|
+
A: Only in development (~0.3ms per update). Production builds have zero overhead.
|
|
408
|
+
|
|
409
|
+
**Q: Do I have to change my code?**
|
|
410
|
+
A: No. The Babel plugin instruments hooks automatically.
|
|
411
|
+
|
|
412
|
+
**Q: What if it flags something that's not a problem?**
|
|
413
|
+
A: Use your judgment. Basis is a diagnostic tool that points out patterns worth investigating - not all flagged patterns are bugs.
|
|
414
|
+
|
|
415
|
+
**Q: How is this different from Redux DevTools?**
|
|
416
|
+
A: Redux DevTools shows state values and action history. Basis shows temporal relationships between state variables, regardless of what state management library you use.
|
|
417
|
+
|
|
418
|
+
**Q: Why "basis"?**
|
|
419
|
+
A: In linear algebra, a "basis" is a minimal set of independent vectors. The name reflects the goal of finding your app's minimal independent state - removing redundancy.
|
|
420
|
+
|
|
421
|
+
**Q: How is this different from Redux DevTools?**
|
|
422
|
+
A: Redux DevTools is a **Journal** - it logs specific values and actions within a Redux store. Basis is an **Architectural Auditor** - it instruments React's core primitives (useState, useReducer, useEffect) to detect hidden relationships between entirely separate components and hooks, even when they don't share a store. Redux DevTools answers "what changed and why?" while Basis answers "is this state architecture clean?"
|
|
423
|
+
|
|
424
|
+
---
|
|
425
|
+
|
|
426
|
+
## Contributing
|
|
427
|
+
|
|
428
|
+
Found a bug? Have an idea? Open an issue or PR.
|
|
429
|
+
|
|
430
|
+
For technical details on how the detection works, see the [Wiki](https://github.com/liovic/react-state-basis/wiki).
|
|
431
|
+
|
|
432
|
+
---
|
|
433
|
+
|
|
434
|
+
<div align="center">
|
|
435
|
+
|
|
436
|
+
Built by [LP](https://github.com/liovic) β’ MIT License
|
|
215
437
|
|
|
216
|
-
|
|
438
|
+
</div>
|