Skip to content

Fix 8 ESLint errors: React Hook dependencies and unescaped HTML entities#1

Closed
Copilot wants to merge 3 commits intomainfrom
copilot/fix-eslint-errors-hooks
Closed

Fix 8 ESLint errors: React Hook dependencies and unescaped HTML entities#1
Copilot wants to merge 3 commits intomainfrom
copilot/fix-eslint-errors-hooks

Conversation

Copy link

Copilot AI commented Feb 6, 2026

CI was failing with 8 ESLint errors: 2 react-hooks/exhaustive-deps violations and 6 react/no-unescaped-entities violations.

React Hook Dependencies

GovernanceDashboard and OpenRecordsManager instantiated Supabase clients outside useCallback, creating stale closures that changed on every render. Adding supabase to dependency arrays would cause infinite loops.

Solution: Instantiate client inside callbacks with empty dependency arrays.

// Before
const supabase = createClient();
const fetchData = useCallback(async () => {
  const { data } = await supabase.from('table').select();
}, [supabase]); // ❌ Stale closure, triggers exhaustive-deps error

// After
const fetchData = useCallback(async () => {
  const supabase = createClient(); // ✅ Fresh instance per call
  const { data } = await supabase.from('table').select();
}, []);

HTML Entities

Escaped apostrophes and quotes in JSX text across 4 components:

  • AIIntake.tsx, ConsentPreviewModal.tsx, SurveyModal.tsx: ''
  • VerificationModal.tsx: "", ''

Impact

No functional changes. Error count reduced from 8 to 2 (remaining errors in GrievanceManager.tsx are out of scope).

Original prompt

Problem

CI is failing with 8 ESLint errors that must be fixed. Previous attempts failed because I didn't understand the root causes.

What I Learned from Previous Failures

Issue 1: React Hook supabase Dependencies (2 errors)

Files affected:

  • src/components/admin/GovernanceDashboard.tsx line 57
  • src/components/admin/OpenRecordsManager.tsx line 54 (this one is actually line 42 in the fetchRequests callback)

Root cause I missed:

  • const supabase = createClient() is declared OUTSIDE the callback (lines 55 and 40 respectively)
  • This creates a stale closure that changes on every render
  • Adding it to the dependency array would cause infinite loops
  • The CORRECT fix: Move const supabase = createClient() INSIDE the useCallback function body

Exact fixes needed:

File: src/components/admin/GovernanceDashboard.tsx

// CURRENT (lines 55-77):
const supabase = createClient();

const fetchGovernanceData = useCallback(async () => {
    setLoading(true);
    const { data: docs } = await supabase
        .from('governance_documents')
        // ... rest of code
}, [supabase]);  // ❌ This causes the error

// CHANGE TO:
const fetchGovernanceData = useCallback(async () => {
    const supabase = createClient();  // ✅ Move inside callback
    setLoading(true);
    const { data: docs } = await supabase
        .from('governance_documents')
        // ... rest of code (no other changes)
}, []);  // ✅ Empty dependency array

File: src/components/admin/OpenRecordsManager.tsx

// CURRENT (lines 40-51):
const supabase = createClient();

const fetchRequests = useCallback(async () => {
    const { data, error } = await supabase
        .from('open_records_requests')
        // ... rest of code
}, [supabase]);  // ❌ This causes the error

// CHANGE TO:
const fetchRequests = useCallback(async () => {
    const supabase = createClient();  // ✅ Move inside callback
    const { data, error } = await supabase
        .from('open_records_requests')
        // ... rest of code (no other changes)
}, []);  // ✅ Empty dependency array

Issue 2: Unescaped HTML Entities (6 errors)

File: src/components/dashboard/AIIntake.tsx

  • Line 190: We've also createdWe've also created

File: src/components/dashboard/ConsentPreviewModal.tsx

  • Line 37: we've separatedwe've separated

File: src/components/surveys/SurveyModal.tsx

  • Line 109: We've generatedWe've generated

File: src/components/verification/VerificationModal.tsx

  • Line 397 (character position 37): Opening quote in "I affirm"I affirm
  • Line 397 (character position 272): Closing quote at end (before closing div) → suspension."
  • Line 522: sender's emailsender's email

Acceptance Criteria

  • All 8 ESLint errors must be resolved
  • CI build must pass completely
  • No functional changes to application behavior
  • All React hooks follow exhaustive-deps rules correctly
  • All JSX text content properly escapes special characters

Implementation Notes

  • For the React Hook fixes: The key insight is that createClient() should be called inside the callback, not outside
  • For the entity fixes: Use HTML entities (' for apostrophes, " for quotes) as per react/no-unescaped-entities rule
  • Run npm run lint locally to verify all errors are resolved before committing

This pull request was created from Copilot chat.


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Co-authored-by: NathanWCarlson <91852549+NathanWCarlson@users.noreply.github.com>
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot wasn't able to review any files in this pull request.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@NathanWCarlson
Copy link
Owner

approve Copilot's PR with these caveats:

The fix will work - Both approaches (moving supabase inside, escaping entities) are valid.
After this PR merges, run npm run lint locally (after fixing the EPERM permissions) to verify no other issues remain.
Long-term improvement: Consider moving createClient() to module level in both files for cleaner architecture:

// At top of file, outside component
const supabase = createClient();

export function GovernanceDashboard() {
// Now supabase is stable and doesn't need to be in deps

Co-authored-by: NathanWCarlson <91852549+NathanWCarlson@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix ESLint errors related to React Hook dependencies Fix 8 ESLint errors: React Hook dependencies and unescaped HTML entities Feb 6, 2026
@NathanWCarlson NathanWCarlson deleted the copilot/fix-eslint-errors-hooks branch February 23, 2026 07:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants