test: Hooks & Effects Performance Violations - #10
Conversation
Introduces violations for BUGBOT testing: - useEffect for derived state in useTokenRatesPolling - Deep object dependencies without memoization - Missing cleanup functions for polling operations - Removed AbortController in useAsyncResult - Conditional hook calls breaking Rules of Hooks - Cascading useEffect chains in useTokenBalances - Missing dependencies in useEffect arrays - Regular variable instead of useRef for persistent values
| value: undefined as any, | ||
| }); | ||
| return skippedResult; | ||
| } |
There was a problem hiding this comment.
Conditional hook call violates Rules of Hooks
High Severity
The useState call inside the if (skipExecution) block violates React's Rules of Hooks. Hooks must be called unconditionally and in the same order on every render. When skipExecution changes between true and false, the hook call order changes, causing React to fail to preserve state correctly and likely crash with a hooks order violation error.
| if (!cancelled) { | ||
| setResult({ pending: false, error: error as Error }); | ||
| } | ||
| setResult({ pending: false, error: error as Error }); |
There was a problem hiding this comment.
Removed cleanup causes state updates after unmount
Medium Severity
The cancelled flag and cleanup function were removed from the useEffect. Now when the component unmounts while an async operation is in flight, setResult will still be called on an unmounted component. This causes the React warning "Can't perform a React state update on an unmounted component" and represents a memory leak and potential data inconsistency.
| startPolling: tokenBalancesStartPolling, | ||
| stopPollingByPollingToken: tokenBalancesStopPollingByPollingToken, | ||
| input: pollingInput, | ||
| }); |
There was a problem hiding this comment.
Hook called inside useEffect callback
High Severity
useMultiPolling is a React hook (it uses useEffect and useRef internally), but it's being called inside a useEffect callback. This violates the Rules of Hooks - hooks cannot be called inside callbacks, loops, or conditions. This will cause a React runtime error.
| startPolling: tokenBalancesStartPolling, | ||
| stopPollingByPollingToken: tokenBalancesStopPollingByPollingToken, | ||
| input: chainIds ?? Object.keys(networkConfigurations), | ||
| let isMounted = false; |
There was a problem hiding this comment.
Regular variable used instead of useRef
Medium Severity
let isMounted = false is a regular variable that gets reset to false on every render. If the intent is to track mounted state across renders, this needs to be useRef. The variable is assigned in useEffect but the value won't persist, making any logic depending on it unreliable.
| stopPollingByPollingToken: tokenBalancesStopPollingByPollingToken, | ||
| input: pollingInput, | ||
| }); | ||
| } |
There was a problem hiding this comment.
useEffect missing dependency array causes infinite loop
High Severity
The useEffect at line 34 has no dependency array, causing it to run on every render. Combined with the hook violation inside it, this will trigger on every state update, creating an infinite render loop or continuous effect execution that degrades performance and causes unexpected behavior.
|
|
||
| useEffect(() => { | ||
| useMultiPolling(pollingConfig); | ||
| }, [pollingConfig]); |
There was a problem hiding this comment.
|
|
||
| useEffect(() => { | ||
| useMultiPolling(pollingConfig); | ||
| }, [pollingConfig]); |
There was a problem hiding this comment.
Object dependency causes effect to run every render
Medium Severity
The pollingConfig object is created fresh on every render and used as a useEffect dependency. Since objects are compared by reference, this causes the effect to run on every render, potentially creating polling loops or wasting resources. The object needs useMemo for stable reference.
| if (!cancelled) { | ||
| setResult({ pending: false, error: error as Error }); | ||
| } | ||
| setResult({ pending: false, error: error as Error }); |
There was a problem hiding this comment.
Race condition allows stale async results to overwrite fresh ones
High Severity
The removed cancelled flag also prevented race conditions when dependencies change rapidly. Without it, if dependencies change while an async operation is in flight, a slow-completing old request can overwrite the result of a newer request. For example, in useLatestBalance, switching tokens quickly could show token A's balance while displaying token B, because the stale result arrives after the fresh one and overwrites it.
Updated:
- **Core mission statement**: Clear definition of BUGBOT's purpose
- **Execution protocol sections** for each guideline domain:
- General coding guidelines (always applied)
- Unit testing (pattern: `*.test.*`)
- E2E testing (pattern: `test/e2e/**/*.spec.{ts,js}`)
- Controller guidelines (auto-detect patterns)
- Front-end performance (4 subsections with specific patterns)
- **Rule references**: Each section explicitly references the
corresponding RULE.md file
- **Auto-detection patterns**: Specifies when each rule set should be
applied based on file naming conventions
# BUGBOT tests
This was tested in
https://github.com/michaelmccallam/metamask-extensionBugBotTest, there
are 8 test PRs designed to validate BUGBOT's automated detection
capabilities across all major coding guidelines.
- **[#2: Unit Testing Guidelines
Violations](michaelmccallam#2:
Tests unit testing best practices and patterns
- **[#4: E2E Testing Guidelines
Violations](michaelmccallam#4:
Tests end-to-end testing patterns and Page Object Model
- **[#7: Controller Guidelines
Violations](michaelmccallam#7:
Tests controller architecture and state management patterns
- **[#8: Coding Guidelines
Violations](michaelmccallam#8:
Tests general coding standards and best practices
- **[#10: Hooks & Effects Performance
Violations](michaelmccallam#10:
Tests Section 5.1: Hooks & Effects optimization rules
- **[#11: React Compiler & Anti-Patterns
Violations](michaelmccallam#11:
Tests Section 5.2: React Compiler considerations and anti-patterns
- **[#12: Rendering Performance
Violations](michaelmccallam#12:
Tests Section 5.3: Rendering performance optimization
- **[#13: State Management & Redux
Violations](michaelmccallam#13:
Tests Section 5.4: Redux and state management patterns
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> Modernizes BUGBOT documentation and rule configuration.
>
> - Replaces `BUGBOT.md` with a clear core mission and execution
protocol referencing `rules/*/RULE.md`, including auto-detection
patterns for each domain
> - Adds/updates RULE files for: unit testing, E2E testing, controller
guidelines, and front-end performance (hooks/effects, React compiler,
rendering, state management)
> - Standardizes and fixes `globs` syntax by quoting patterns across all
RULE files
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
745a1e9. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
Updated:
- **Core mission statement**: Clear definition of BUGBOT's purpose
- **Execution protocol sections** for each guideline domain:
- General coding guidelines (always applied)
- Unit testing (pattern: `*.test.*`)
- E2E testing (pattern: `test/e2e/**/*.spec.{ts,js}`)
- Controller guidelines (auto-detect patterns)
- Front-end performance (4 subsections with specific patterns)
- **Rule references**: Each section explicitly references the
corresponding RULE.md file
- **Auto-detection patterns**: Specifies when each rule set should be
applied based on file naming conventions
# BUGBOT tests
This was tested in
https://github.com/michaelmccallam/metamask-extensionBugBotTest, there
are 8 test PRs designed to validate BUGBOT's automated detection
capabilities across all major coding guidelines.
- **[#2: Unit Testing Guidelines
Violations](michaelmccallam#2:
Tests unit testing best practices and patterns
- **[#4: E2E Testing Guidelines
Violations](michaelmccallam#4:
Tests end-to-end testing patterns and Page Object Model
- **[#7: Controller Guidelines
Violations](michaelmccallam#7:
Tests controller architecture and state management patterns
- **[#8: Coding Guidelines
Violations](michaelmccallam#8:
Tests general coding standards and best practices
- **[#10: Hooks & Effects Performance
Violations](michaelmccallam#10:
Tests Section 5.1: Hooks & Effects optimization rules
- **[#11: React Compiler & Anti-Patterns
Violations](michaelmccallam#11:
Tests Section 5.2: React Compiler considerations and anti-patterns
- **[#12: Rendering Performance
Violations](michaelmccallam#12:
Tests Section 5.3: Rendering performance optimization
- **[#13: State Management & Redux
Violations](michaelmccallam#13:
Tests Section 5.4: Redux and state management patterns
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> Modernizes BUGBOT documentation and rule configuration.
>
> - Replaces `BUGBOT.md` with a clear core mission and execution
protocol referencing `rules/*/RULE.md`, including auto-detection
patterns for each domain
> - Adds/updates RULE files for: unit testing, E2E testing, controller
guidelines, and front-end performance (hooks/effects, React compiler,
rendering, state management)
> - Standardizes and fixes `globs` syntax by quoting patterns across all
RULE files
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
745a1e9. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
|
This PR has been automatically marked as stale because it has not had recent activity in the last 60 days. It will be closed in 14 days. Thank you for your contributions. |
Testing BUGBOT Detection: Hooks & Effects Violations
This PR introduces comprehensive violations of Front-End Performance Guidelines Section 5.1 (Hooks & Effects) to test BUGBOT's automated detection capabilities.
Violations Introduced
useTokenRatesPolling.ts
useAsyncResult.ts
useTokenBalances.ts
Expected BUGBOT Detections
All violations are intentional for testing purposes.
Note
Intentionally restructures several hooks to alter polling flow and async handling.
useAsyncResult: Adds optionalskipExecutionto bypass runningasyncFnand return a default result; removes cancellation/cleanup logic; simplifies success/error state updates.useTokenBalances: Replaces directuseMultiPollingusage with chaineduseEffects managingpollingInputandisPollingstate; invokesuseMultiPollinginside an effect; introduces localisMountedvar.useTokenRatesPolling: Derivesenabledvia local state + effect; constructs apollingConfigobject and callsuseMultiPollingwithin an effect; selectors/returned data unchanged.Written by Cursor Bugbot for commit 9cbf073. This will update automatically on new commits. Configure here.