Skip to content

fix(city): clear pending InstancedBuildings safety timers during lifecycle changes (#291)#414

Open
itssagarK wants to merge 23 commits into
Ixotic27:mainfrom
itssagarK:291-fix-instanced-buildings-timer
Open

fix(city): clear pending InstancedBuildings safety timers during lifecycle changes (#291)#414
itssagarK wants to merge 23 commits into
Ixotic27:mainfrom
itssagarK:291-fix-instanced-buildings-timer

Conversation

@itssagarK

@itssagarK itssagarK commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

This PR fixes a lifecycle issue in InstancedBuildings where delayed initialization timers could continue running after component updates or unmounts.

Previously, the component relied on a timeout-based safety mechanism, but rapid layout changes or component lifecycle transitions could leave pending callbacks scheduled against stale component state and references.

This PR ensures that pending timers are consistently cleaned up before new timers are created and when the component unmounts.

Changes Made

src/components/InstancedBuildings.tsx

  • Added a persistent timerRef using useRef.
  • Stored the active timeout reference in timerRef.
  • Cleared any existing timer before scheduling a new one.
  • Updated the effect cleanup function to always clear pending timers.
  • Prevented delayed callbacks from executing after lifecycle changes.

Why this matters

Without this fix:

  • Delayed callbacks may execute after component updates.
  • Multiple timers can accumulate during rapid layout changes.
  • Operations may run against stale references.
  • Unnecessary work may continue after unmount.

With this fix:

  • Only one active safety timer exists at a time.
  • Pending timers are cleaned up correctly.
  • Lifecycle transitions remain safe and predictable.
  • Unnecessary callback execution is prevented.

Related Issue

Fixes #291

Checklist

  • npm run lint passes
  • Tested locally
  • No secrets or .env values committed
  • I acknowledge that an automated AI Reviewer will perform a preliminary review of this PR.
  • I have starred this repository! (We prioritize PRs and assignments for stargazers)

@vercel

vercel Bot commented Jun 8, 2026

Copy link
Copy Markdown

@itssagarK is attempting to deploy a commit to the ixotic27-8245's projects Team on Vercel.

A member of the Team first needs to authorize it.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Security Scan: Clean

No suspicious patterns detected. The official Copilot bot will provide detailed AI feedback shortly.

If you enjoyed contributing, please consider starring the repository!

@github-actions github-actions Bot added frontend good first issue Good for newcomers Gssoc 26 Part of GirlScript Summer of Code 2026 gssoc:approved Approved GSSoC contribution level:intermediate Intermediate difficulty level type:bug Something isn't working as expected labels Jun 8, 2026
@itssagarK

Copy link
Copy Markdown
Contributor Author

Hi @Ixotic27,

I've submitted a fix for #291.

This PR introduces a persistent timer reference and ensures pending safety timers are cleared both before new timers are scheduled and during component cleanup.

The goal is to prevent delayed callbacks from executing after lifecycle changes and avoid unnecessary work on stale references.

Thank you for reviewing.

@Ixotic27

Ixotic27 commented Jun 8, 2026

Copy link
Copy Markdown
Owner

Hi @itssagarK! 👋 I've reviewed your PR code for resolving issue #291.

There is a React Hook rule violation in src/components/InstancedBuildings.tsx (on line 389/390 in the diff):

    const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null);

You declared timerRef using the useRef hook inside a useEffect callback block. According to the Rules of Hooks, hooks can only be called at the top level of function components and cannot be nested inside hooks or callbacks. This will throw a runtime error in the browser.

Since the useEffect cleanup function has a closure over variables declared inside the effect, you can simply declare a normal local variable (e.g., let safetyTimer: ReturnType<typeof setTimeout> | null = null;) inside the useEffect body to manage this, or declare timerRef at the top level of the InstancedBuildings component.

Please fix this so we can merge your changes! Thank you!

@github-actions github-actions Bot added the status:blocked This PR is blocked due to a failing CI check. label Jun 9, 2026
@github-actions

github-actions Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

🚨 Hey @itssagarK, the CI Pipeline is failing on this PR and it has been marked as status:blocked.

🔍 What failed:

  • Production Build failed at step(s): Build

📋 Error Details (first 2):

Please fix the issues before this can be reviewed. Here's how:

1. Run checks locally before pushing:

npm run lint           # Run ESLint
npm run build          # Verify production build passes

2. Auto-fix common issues:

npm run lint -- --fix  # Auto-fix lint errors where possible

3. Check the full failure log here:
👉 View CI Run

Once you push a fix and the CI passes, the status:blocked label will be removed automatically. 💪

@github-actions github-actions Bot removed the status:blocked This PR is blocked due to a failing CI check. label Jun 9, 2026
Ixotic27 and others added 6 commits June 9, 2026 14:19
I've updated the implementation and removed the Hook usage from inside the effect. The timer is now managed using a local `safetyTimer` variable within the effect scope and is cleared during cleanup whenever dependencies change or the component unmounts.

This keeps the solution aligned with React's Rules of Hooks while preserving the intended timer cleanup behavior.
@itssagarK

Copy link
Copy Markdown
Contributor Author

Hi @Ixotic27,

Thank you for the review.

I've updated the implementation and removed the Hook usage from inside the effect. The timer is now managed using a local safetyTimer variable within the effect scope and is cleared during cleanup whenever dependencies change or the component unmounts.

This keeps the solution aligned with React's Rules of Hooks while preserving the intended timer cleanup behavior.

Thank you for the feedback. Please take another look when you have time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

frontend good first issue Good for newcomers gssoc:approved Approved GSSoC contribution Gssoc 26 Part of GirlScript Summer of Code 2026 level:intermediate Intermediate difficulty level type:bug Something isn't working as expected

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: InstancedBuildings safety timer is not cleared during component lifecycle changes

2 participants