Using Map method with React causes infinite recursion
See original GitHub issueI am not 100% sure what’s happening as my research was limited. Still I’ll try to explain the problem.
var constants = immutable({
BASE_PATH: '/my/files'
}),
BASE = constants.BASE_PATH,
menu = [
{
link: BASE,
title: 'Files'
},
{
link: `${BASE}/:sharing`,
title: 'Sharing'
}
];
…
render() {
var moreParams = ( this.props.params.splat || '' ).split('/'),
command = moreParams.length && moreParams[0].charAt(0) == ':' ? moreParams[0].substr(1) : null;
return (
<div className="_personal-storage">
<Menu items={ menu } />
<Storage base={ BASE } callback={ processCommand }>
<h1>Personal storage</h1>
</Storage>
</div>
);
}
Everything works this way, but as soon as I make menu
immutable, it goes to the weirdest infinite recursion in seamless-immutable.js:
Uncaught RangeError: Maximum call stack size exceeded
defineProperty @ (program):779
addPropertyTo @ seamless-immutable.js:5
makeImmutableObject @ seamless-immutable.js:342
Immutable @ seamless-immutable.js:371
Immutable @ seamless-immutable.js:367
Immutable @ seamless-immutable.js:367
Immutable @ seamless-immutable.js:367
makeImmutableArray @ seamless-immutable.js:106
Immutable @ seamless-immutable.js:354
Immutable @ seamless-immutable.js:367
The weirdest part is - it happens only if I pass menu
as a property to a react component. If I just log it to the console it works just fine. It doesn’t matter if I make it immutable on declaration or later - it works the same.
When I’ve been debugging it, I couldn’t believe my eyes - after making immutable my objects, it started making immutable React stuff {$$typeof: Symbol(react.element), key: null, ref: null, props: Object, _owner: ReactCompositeComponentWrapper…}$$typeof: Symbol(react.element)_owner: ReactCompositeComponentWrapper_self: null_source: null_store: Objectkey: nullprops: Objectref: nulltype: _default(props)__proto__: Object
and this is where the infinite recursion happens. But why does it make it immutable at all? I have no idea.
Issue Analytics
- State:
- Created 8 years ago
- Comments:19 (8 by maintainers)
Hi! I just wanted to contribute my two cents to this issue. First, let me say that I love seamless-immutable and this issue currently prevents me to use it at a massive scale for react applications. There are two workarounds for this issue:
Or, as mentioned above:
In my opinion, we are loosing the notion of “seamless” here. I’m setting up projects for people new to React to get them started easily. Basically, I will tell them: “This is seamless until you use it in a React component”. That’s a leaky abstraction.
I wonder if the use case of mapping elements to another immutable collection is as frequent as you think. By mapping elements, you are basically transforming your
Array<X>
to anotherArray<Y>
. So it’s a conscious decision and most of the time, I’ll be using a transform for read-only operations.Introducing a
mapToImmutable()
function and lettingmap()
return a mutable array is another solution to this problem.What do you think?
Fixed and published as 6.0.1! Big ups to @davidblurton for the implementation.
I’m going to wait about a week before announcing this release, so people have a chance to kick the tires and see if we missed anything. 😸