immerjs / immer

Create the next immutable state by mutating the current one
https://immerjs.github.io/immer/
MIT License
27.65k stars 848 forks source link

"Maximum call stack exceeded" with circular references #1106

Open joshkel opened 7 months ago

joshkel commented 7 months ago

πŸ› Bug Report

Starting with Immer 10.0.4, if Immer is given an object that uses symbols for circular references, it generates a "Maximum call stack exceeded" error.

Link to repro

https://playcode.io/1794809

To Reproduce

Pass an object with pre-existing symbol circular references to Immer 10.0.4. (Circular references that are added within an Immer recipe do not cause problems.)

Observed behavior

"Maximum call stack exceeded"

Expected behavior

Our application uses symbols to create child-to-parent relationships. Since symbols are skipped by many JavaScript routines (e.g., JSON.stringify, Immer prior to 10.0.4), we had been able to do this without error.

Environment

mweststrate commented 7 months ago

Argh, the JS world is impossible. 50% is like "non-enumerables and proxies have very specific meanings", and the other half is like "I expect non-enumerables and symbol to work just like the rest, why treat them irregularly" 🀣

mweststrate commented 7 months ago

Would you mind trying setting the setUseStrictShallowCopy(false) flag? Maybe in combination with version 10.0.4-beta?

joshkel commented 7 months ago

@mweststrate I get it. I apologize for contributing to your pain as an open-source maintainer.

setUseStrictShallowCopy(false) with 10.0.4 or 10.0.4-beta seems to have no effect.

For what it's worth, Immer 9.x's behavior seemed consistent and worked for my purposes:

Hopefully that's too ad hoc / too much of a special case - but, if you decide it is, I understand.

NMinhNguyen commented 7 months ago

Another way to reproduce this is trying to modify an object that contains React context: https://codesandbox.io/p/devbox/festive-gagarin-9mkfx9

For what it’s worth, the repro seems to work using immer@6.0.9

mweststrate commented 5 months ago

Yeah I guess the only way to deal with this is to make all the behavior of irregular properties of any kind (enumerable x getter x proxy) all configurable. That will be a a bit bigger project though so probably more for a next major.