react-state-basis 0.3.4 → 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 +236 -114
- 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 +1 -1
package/README.md
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
[](https://github.com/liovic/react-state-basis/stargazers)
|
|
12
12
|
[](https://opensource.org/licenses/MIT)
|
|
13
13
|
|
|
14
|
-
**Catches redundant state and update chains
|
|
14
|
+
**Catches redundant state and update chains using temporal cross-correlation.**
|
|
15
15
|
|
|
16
16
|
</div>
|
|
17
17
|
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
- **Infinite loops** - Circular dependencies that freeze your browser
|
|
27
27
|
- **Tight coupling** - State variables that should be independent but aren't
|
|
28
28
|
|
|
29
|
-
It works by tracking *when* state updates happen, not *what* the values are.
|
|
29
|
+
It works by tracking *when* state updates happen (temporal patterns), not *what* the values are.
|
|
30
30
|
|
|
31
31
|
---
|
|
32
32
|
|
|
@@ -37,7 +37,7 @@ const [user, setUser] = useState(null);
|
|
|
37
37
|
const [isLoggedIn, setIsLoggedIn] = useState(false);
|
|
38
38
|
|
|
39
39
|
useEffect(() => {
|
|
40
|
-
setIsLoggedIn(!!user); // Double render - flagged as
|
|
40
|
+
setIsLoggedIn(!!user); // Double render - flagged as sync leak
|
|
41
41
|
}, [user]);
|
|
42
42
|
|
|
43
43
|
// ✅ Better
|
|
@@ -49,7 +49,7 @@ const isLoggedIn = !!user; // Computed, no second render
|
|
|
49
49
|
|
|
50
50
|
## See It Work
|
|
51
51
|
|
|
52
|
-
The optional HUD shows
|
|
52
|
+
The optional HUD shows your state basis matrix in real-time:
|
|
53
53
|
|
|
54
54
|
<p align="center">
|
|
55
55
|
<img src="./assets/react-state-basis.gif" width="800" alt="React State Basis Demo" />
|
|
@@ -57,6 +57,32 @@ The optional HUD shows which states update together in real-time:
|
|
|
57
57
|
|
|
58
58
|
---
|
|
59
59
|
|
|
60
|
+
## Real-World Audits
|
|
61
|
+
|
|
62
|
+
Basis has been tested on major open-source projects to validate detection accuracy:
|
|
63
|
+
|
|
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
|
|
68
|
+
|
|
69
|
+
<p align="center">
|
|
70
|
+
<img src="./assets/excalidraw-audit.png" width="800" alt="Excalidraw Audit" />
|
|
71
|
+
</p>
|
|
72
|
+
|
|
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
|
|
77
|
+
|
|
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.
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
60
86
|
## Setup (Vite)
|
|
61
87
|
|
|
62
88
|
### 1. Install
|
|
@@ -91,7 +117,19 @@ root.render(
|
|
|
91
117
|
);
|
|
92
118
|
```
|
|
93
119
|
|
|
94
|
-
|
|
120
|
+
### 4. Verify It's Working
|
|
121
|
+
|
|
122
|
+
Add this test pattern to any component:
|
|
123
|
+
```tsx
|
|
124
|
+
const [a, setA] = useState(0);
|
|
125
|
+
const [b, setB] = useState(0);
|
|
126
|
+
|
|
127
|
+
useEffect(() => {
|
|
128
|
+
setB(a); // Basis will flag this
|
|
129
|
+
}, [a]);
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Trigger an update (e.g., click a button that calls `setA(1)`). You should see a console alert within ~100ms.
|
|
95
133
|
|
|
96
134
|
---
|
|
97
135
|
|
|
@@ -99,213 +137,297 @@ That's it. The tool runs automatically in development.
|
|
|
99
137
|
|
|
100
138
|
### Console Alerts
|
|
101
139
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
**Redundant State:**
|
|
140
|
+
**Redundant Pattern:**
|
|
141
|
+
Detected when two variables move in perfect unison.
|
|
105
142
|
```
|
|
106
|
-
📐 BASIS | REDUNDANT
|
|
143
|
+
📐 BASIS | REDUNDANT PATTERN
|
|
107
144
|
📍 Location: TodoList.tsx
|
|
108
|
-
|
|
109
|
-
One is likely
|
|
110
|
-
|
|
111
|
-
Suggested fix: Convert "count" to a computed value
|
|
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.
|
|
112
148
|
```
|
|
113
149
|
|
|
114
|
-
**
|
|
150
|
+
**Sync Leak (Causal Chain):**
|
|
151
|
+
Detected when one variable consistently triggers another with a temporal lag.
|
|
115
152
|
```
|
|
116
|
-
💡 BASIS |
|
|
117
|
-
|
|
118
|
-
|
|
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.
|
|
119
158
|
```
|
|
120
159
|
|
|
121
|
-
**Infinite
|
|
160
|
+
**Infinite Loop:**
|
|
161
|
+
Detected when a variable updates too rapidly (circuit breaker).
|
|
122
162
|
```
|
|
123
|
-
🛑 BASIS |
|
|
124
|
-
|
|
125
|
-
Execution halted to prevent browser
|
|
163
|
+
🛑 BASIS CRITICAL | CIRCUIT BREAKER
|
|
164
|
+
Infinite oscillation detected on: "counter"
|
|
165
|
+
Execution halted to prevent browser thread lock.
|
|
126
166
|
```
|
|
127
167
|
|
|
128
168
|
### Health Report
|
|
129
169
|
|
|
130
|
-
Check your entire app's state
|
|
170
|
+
Check your entire app's state architecture:
|
|
131
171
|
```tsx
|
|
132
172
|
window.printBasisReport();
|
|
133
173
|
```
|
|
134
174
|
|
|
135
175
|
Shows:
|
|
136
|
-
-
|
|
137
|
-
-
|
|
138
|
-
- Correlation
|
|
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)
|
|
139
179
|
|
|
140
180
|
---
|
|
141
181
|
|
|
142
|
-
##
|
|
182
|
+
## How It Works (v0.4.0)
|
|
143
183
|
|
|
144
|
-
|
|
184
|
+
### Temporal Cross-Correlation
|
|
145
185
|
|
|
146
|
-
|
|
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
|
+
```
|
|
147
192
|
|
|
148
|
-
|
|
149
|
-
**Issue:** Double render on every theme change
|
|
150
|
-
**Fix:** [PR #10637](https://github.com/excalidraw/excalidraw/pull/10637) - replaced with computed value
|
|
151
|
-
**Status:** Pending review
|
|
193
|
+
For every pair of variables, Basis checks three temporal relationships:
|
|
152
194
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
195
|
+
1. **Synchronous (Redundancy):** Do they update in the same tick?
|
|
196
|
+
```
|
|
197
|
+
A: [0,1,0,1,0,...]
|
|
198
|
+
B: [0,1,0,1,0,...] → Flagged as redundant
|
|
199
|
+
```
|
|
156
200
|
|
|
157
|
-
|
|
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
|
+
```
|
|
158
206
|
|
|
159
|
-
**
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
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
|
+
```
|
|
163
212
|
|
|
164
|
-
|
|
165
|
-
<img src="./assets/shadcn-admin.png" width="800" alt="shadcn Admin Audit" />
|
|
166
|
-
</p>
|
|
213
|
+
The engine uses **offset-based comparison** to check these patterns without allocating temporary arrays, ensuring minimal overhead even at high frame rates.
|
|
167
214
|
|
|
168
|
-
|
|
215
|
+
### Performance Optimizations
|
|
169
216
|
|
|
170
|
-
|
|
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
|
|
171
221
|
|
|
172
|
-
|
|
222
|
+
### What Gets Flagged?
|
|
173
223
|
|
|
174
|
-
|
|
224
|
+
**Redundant Pattern Example:**
|
|
225
|
+
```tsx
|
|
226
|
+
// ❌ Before (Basis flags this)
|
|
227
|
+
const [count, setCount] = useState(0);
|
|
228
|
+
const [doubled, setDoubled] = useState(0);
|
|
175
229
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
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]);
|
|
181
237
|
```
|
|
182
238
|
|
|
183
|
-
|
|
239
|
+
**Sync Leak Example:**
|
|
240
|
+
```tsx
|
|
241
|
+
// ❌ Before (causes double render)
|
|
242
|
+
const [user, setUser] = useState(null);
|
|
243
|
+
const [isLoggedIn, setIsLoggedIn] = useState(false);
|
|
184
244
|
|
|
185
|
-
|
|
245
|
+
useEffect(() => {
|
|
246
|
+
setIsLoggedIn(!!user);
|
|
247
|
+
}, [user]);
|
|
186
248
|
|
|
187
|
-
|
|
249
|
+
// ✅ After (single render)
|
|
250
|
+
const [user, setUser] = useState(null);
|
|
251
|
+
const isLoggedIn = !!user; // Derived, no effect needed
|
|
252
|
+
```
|
|
188
253
|
|
|
189
|
-
|
|
190
|
-
- Redundant state → always updates together
|
|
191
|
-
- Update chains → one state updates, then another follows
|
|
192
|
-
- Infinite loops → same state updates rapidly
|
|
254
|
+
---
|
|
193
255
|
|
|
194
|
-
|
|
256
|
+
## Upgrading from v0.3.x
|
|
195
257
|
|
|
196
|
-
###
|
|
258
|
+
### Breaking Changes
|
|
259
|
+
None! v0.4.0 is a drop-in replacement.
|
|
197
260
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
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
|
|
202
266
|
|
|
203
|
-
|
|
267
|
+
### Action Required
|
|
268
|
+
None. Just update the package and restart your dev server.
|
|
269
|
+
```bash
|
|
270
|
+
npm update react-state-basis
|
|
271
|
+
```
|
|
204
272
|
|
|
205
273
|
---
|
|
206
274
|
|
|
207
275
|
## Production Safety
|
|
208
276
|
|
|
209
|
-
In production builds, the entire tool is
|
|
277
|
+
In production builds, the entire tool is replaced with zero-op shims. **Zero runtime overhead. Zero bundle size increase.**
|
|
210
278
|
```json
|
|
211
279
|
// package.json - automatic based on NODE_ENV
|
|
212
280
|
"exports": {
|
|
213
281
|
".": {
|
|
214
282
|
"development": "./dist/index.mjs",
|
|
215
|
-
"production": "./dist/production.mjs", //
|
|
283
|
+
"production": "./dist/production.mjs", // No-op shims
|
|
216
284
|
"default": "./dist/production.mjs"
|
|
217
285
|
}
|
|
218
286
|
}
|
|
219
287
|
```
|
|
220
288
|
|
|
221
|
-
|
|
289
|
+
---
|
|
290
|
+
|
|
291
|
+
## When to Skip Files
|
|
292
|
+
|
|
293
|
+
Add `// @basis-ignore` at the top of a file to disable instrumentation:
|
|
294
|
+
```tsx
|
|
295
|
+
// @basis-ignore
|
|
296
|
+
// This file uses high-frequency animations and intentional state synchronization
|
|
297
|
+
```
|
|
298
|
+
|
|
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)
|
|
222
305
|
|
|
223
306
|
---
|
|
224
307
|
|
|
225
308
|
## Comparison to Other Tools
|
|
226
309
|
|
|
227
|
-
| Tool |
|
|
228
|
-
|
|
229
|
-
| **React DevTools** | Component
|
|
230
|
-
| **Why Did You Render** |
|
|
231
|
-
| **ESLint exhaustive-deps** |
|
|
232
|
-
| **react-state-basis** |
|
|
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** |
|
|
233
316
|
|
|
234
|
-
|
|
317
|
+
These tools are complementary - use them together for best results.
|
|
235
318
|
|
|
236
319
|
---
|
|
237
320
|
|
|
238
|
-
##
|
|
321
|
+
## Performance Impact (Measured)
|
|
239
322
|
|
|
240
|
-
|
|
241
|
-
```tsx
|
|
242
|
-
// @basis-ignore
|
|
243
|
-
```
|
|
323
|
+
**Development Mode**
|
|
244
324
|
|
|
245
|
-
|
|
246
|
-
- Animation loops
|
|
247
|
-
- High-frequency timers
|
|
248
|
-
- WebSocket handlers
|
|
249
|
-
- Performance-critical code
|
|
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.
|
|
250
326
|
|
|
251
|
-
|
|
327
|
+
Location: `/example`
|
|
328
|
+
|
|
329
|
+
**Observed impact:**
|
|
252
330
|
|
|
253
|
-
|
|
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
|
|
254
335
|
|
|
255
|
-
|
|
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
|
|
348
|
+
|
|
349
|
+
---
|
|
350
|
+
|
|
351
|
+
## Limitations (v0.4.0)
|
|
256
352
|
|
|
257
353
|
**What works well:**
|
|
258
|
-
- ✅ Detecting
|
|
259
|
-
- ✅ Flagging effect-driven update chains
|
|
260
|
-
- ✅ Catching infinite loops
|
|
261
|
-
- ✅
|
|
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
|
|
262
358
|
|
|
263
|
-
**Known
|
|
264
|
-
- ⚠️
|
|
265
|
-
- ⚠️
|
|
266
|
-
- ⚠️ Complex multi-way dependencies might not
|
|
267
|
-
- ⚠️ Requires judgment
|
|
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
|
|
268
364
|
|
|
269
|
-
**False positives happen.** Always verify before refactoring.
|
|
365
|
+
**False positives can happen.** Always verify before refactoring.
|
|
270
366
|
|
|
271
367
|
---
|
|
272
368
|
|
|
273
369
|
## Roadmap
|
|
274
370
|
|
|
275
|
-
### v0.
|
|
276
|
-
- [ ] Zustand integration
|
|
277
|
-
- [ ]
|
|
278
|
-
- [ ]
|
|
279
|
-
- [ ]
|
|
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
|
|
280
376
|
|
|
281
|
-
###
|
|
282
|
-
- [ ]
|
|
283
|
-
- [ ]
|
|
284
|
-
- [ ]
|
|
377
|
+
### Future Ideas
|
|
378
|
+
- [ ] Domain isolation analysis (detect feature boundaries)
|
|
379
|
+
- [ ] Export audit reports for team reviews
|
|
380
|
+
- [ ] CI integration for architectural regressions
|
|
285
381
|
|
|
286
382
|
---
|
|
287
383
|
|
|
288
|
-
##
|
|
384
|
+
## Troubleshooting
|
|
289
385
|
|
|
290
|
-
|
|
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`
|
|
291
391
|
|
|
292
|
-
|
|
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
|
|
396
|
+
|
|
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
|
|
293
401
|
|
|
294
402
|
---
|
|
295
403
|
|
|
296
404
|
## FAQ
|
|
297
405
|
|
|
298
406
|
**Q: Will this slow down my app?**
|
|
299
|
-
A: Only in development. Production builds
|
|
407
|
+
A: Only in development (~0.3ms per update). Production builds have zero overhead.
|
|
300
408
|
|
|
301
409
|
**Q: Do I have to change my code?**
|
|
302
410
|
A: No. The Babel plugin instruments hooks automatically.
|
|
303
411
|
|
|
304
412
|
**Q: What if it flags something that's not a problem?**
|
|
305
|
-
A: Use your judgment.
|
|
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.
|
|
306
417
|
|
|
307
418
|
**Q: Why "basis"?**
|
|
308
|
-
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.
|
|
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).
|
|
309
431
|
|
|
310
432
|
---
|
|
311
433
|
|