Skip to content

Commit

Permalink
[FIX] reactivity: do not crash when reading reactive frozen objects
Browse files Browse the repository at this point in the history
This crash was caused by the fact that Proxies *must* return the value of the
property on the target when that property is non-writeable and
non-configurable. Since the reactivity system always attempts to proxify the
value from the target, this crashes.

This commit fixes that by not proxifying such values. This however means that
from that point on, we have escaped the reactivity system and will not
subscribe to any changes in that object or its children.
  • Loading branch information
sdegueldre authored and ged-odoo committed Mar 28, 2022
1 parent c7d515a commit 7611ea6
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 0 deletions.
5 changes: 5 additions & 0 deletions src/reactivity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,11 @@ function basicProxyHandler<T extends Target>(callback: Callback): ProxyHandler<T
if (key === TARGET) {
return target;
}
// non-writable non-configurable properties cannot be made reactive
const desc = Object.getOwnPropertyDescriptor(target, key);
if (desc && !desc.writable && !desc.configurable) {
return Reflect.get(target, key, proxy);
}
observeTargetKey(target, key, callback);
return possiblyReactive(Reflect.get(target, key, proxy), callback);
},
Expand Down
7 changes: 7 additions & 0 deletions tests/reactivity.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1095,6 +1095,13 @@ describe("Reactivity", () => {
expect(n).toBe(1);
expect(state.k).toEqual({ n: 2 });
});

test("can access properties on reactive of frozen objects", async () => {
const obj = Object.freeze({ a: {} });
const state = createReactive(obj);
expect(() => state.a).not.toThrow();
expect(state.a).toBe(obj.a);
});
});

describe("Collections", () => {
Expand Down

0 comments on commit 7611ea6

Please sign in to comment.