Skip to content

Fix/prevent render after unmount#32

Open
ZvozdaB wants to merge 2 commits intoxjpro:masterfrom
ZvozdaB:fix/prevent-render-after-unmount
Open

Fix/prevent render after unmount#32
ZvozdaB wants to merge 2 commits intoxjpro:masterfrom
ZvozdaB:fix/prevent-render-after-unmount

Conversation

@ZvozdaB
Copy link
Contributor

@ZvozdaB ZvozdaB commented Mar 4, 2026

Summary

Resolves #33

  • Add _destroyed flag set in $onDestroy to guard against late lifecycle calls
  • Guard $doCheck and $onChanges with early return when _destroyed is true
  • Prevents React 19 "Cannot update an unmounted root" error when AngularJS fires $onChanges after $onDestroy in the same digest cycle
  • Improve TypeScript declarations: replace incorrect React.Element with ComponentType<TProps>, add generic bindings constraint
  • Bump version 18.0.018.0.1

Problem

AngularJS does not guarantee that $onChanges won't fire after $onDestroy when both a binding change and component destruction occur in the same digest cycle. This causes root.render() to be called on an already-unmounted React root.

Changes

src/index.js (3 lines added):

          this.$doCheck = () => {
+           if (this._destroyed) return;
            for (let previousKey of Object.keys(previous)) {

          this.$onChanges = () => {
+           if (this._destroyed) return;
            this.root.render(React.createElement(Component, this));
          };

          this.$onDestroy = () => {
+           this._destroyed = true;
            this.root.unmount();
          };

index.d.ts — improved type declarations:

  • React.ElementComponentType<TProps> (was incorrectly typed as JSX element instead of component)
  • bindings: any{ [K in keyof TProps]?: '<' | '=' | '@' | '&' } (type-safe mapping of component props to AngularJS binding types)
  • Added generic <TProps> to link component props with bindings

index.js — regenerated via npm run build
package.json — version bump to 18.0.1

Test plan

  • Verify angularized component renders normally with < and = bindings
  • Trigger simultaneous binding change + route navigation in same digest — confirm no "Cannot update an unmounted root" error
  • Verify component cleanup still works (no memory leaks from orphaned roots)
  • Verify TypeScript compilation with new type declarations

ZvozdaB added 2 commits March 4, 2026 14:47
… after $onDestroy

Add _destroyed flag in $onDestroy and guard $doCheck/$onChanges with
early return to avoid "Cannot update an unmounted root" error in React 19
when AngularJS fires $onChanges after $onDestroy in the same digest cycle.

Bump version to 18.0.1.

Made-with: Cursor
Replace incorrect React.Element with ComponentType<TProps>, add generic
bindings constraint to map component props to AngularJS binding types.

Made-with: Cursor
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.

$onChanges fires after $onDestroy causing "Cannot update an unmounted root" in React 19

1 participant