-
-
Notifications
You must be signed in to change notification settings - Fork 17
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Complex selectors with immer #74
Comments
Thanks for reporting. |
Yeah, this simple test succeeds, strangely. The complex case also succeeds in proxy-memoize 1.2.0, but 2.0.0 seems to break it. import { memoize } from "proxy-memoize";
import { produce } from "immer";
import { describe, it, expect } from "@jest/globals";
describe("selectors w/ immer", () => {
it("works", () => {
let state = Object.freeze({
x: {
y: {
z: [{ m: 3 }],
},
},
q: {
n: {
mm: 21,
},
},
});
const selectorOne = memoize((s: typeof state) => {
return s.x.y.z[0];
});
expect(selectorOne(state)).toEqual({ m: 3 });
state = produce(state, (draft) => {
draft.x.y = { z: [] };
});
// succeeds
expect(selectorOne(state)).toEqual(undefined);
});
}); |
Interesting. Would you be able to dig more into it? |
Oops, scratch that. 2.0.3 works fine for this test and 2.0.4 seems to break it. I'll try to look into it some more. |
I am having the same problem. Using immer + zustand + this library. Seems for me like immer returning objects with changed config for them... |
This solves the issue: import { setAutoFreeze } from "immer";
setAutoFreeze(false); |
@valerii15298 Note that disabling immer's auto freeze will likely result in reduced performance. immerjs/immer#687 To recap, the issue seems to be immer's auto-freeze combined with the target cache from 220bffe returning the non-frozen proxy. This is unfortunate since freezing helps prevent accidental state mutations. But I don't see another workaround outside of reverting 220bffe... |
Recursive proxying frozen objects doesn't simply work. It's JS restriction: $ node
Welcome to Node.js v18.14.0.
Type ".help" for more information.
> obj = { nested: {} }
{ nested: {} }
> Object.freeze(obj.nested)
{}
> Object.freeze(obj)
{ nested: {} }
> p = new Proxy(obj, {
... get(target, prop) { return new Proxy(target[prop], {}) }
... })
Proxy [ { nested: {} }, { get: [Function: get] } ]
> p.nested
Uncaught:
TypeError: 'get' on proxy: property 'nested' is a read-only and non-configurable data property on the proxy target but the proxy did not return its actual value (expected '#<Object>' but got '#<Object>') |
OK, it sounds like we should update the documentation to recommend disabling auto-freeze with immer. Would you like a PR for that? It is strange since I would expect immer is also using nested proxies with frozen objects, but maybe that's not the case... |
Yes, please. |
Hi,
I'm running into an issue when using nested selectors with immer. The test below fails for me.
https://codesandbox.io/s/youthful-grass-14m8cp?file=/src/index.test.js
TypeError: 'get' on proxy: property 'n' is a read-only and non-configurable data property on the proxy target but the proxy did not return its actual value (expected '#<Object>' but got '#<Object>')
Any ideas? Thanks!
The text was updated successfully, but these errors were encountered: