-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Immutable mode for nestedProperty #2418
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
I like the idea of It'll take a bit of work to get this integrated with plotly.js, and I'd like to have a clear idea how that will work before we add this to the library. My main concern is that |
@alexcjohnson That shouldn't be a problem, the update can be applied further up the state tree in an immutable fashion as well. For example with const prop = nestedProperty(layout.xaxis, attr);
const newXaxis = prop.setImmutable(value);
const newLayout = update(layout, { xaxis: { $set: newXaxis } }); Or with the (ES6) spread operator: const prop = nestedProperty(layout.xaxis, attr);
const newXaxis = prop.setImmutable(value);
const newLayout = { ...layout, xaxis: newXaxis }; And for an array like const trace = data[traceIndex];
const prop = nestedProperty(trace, attr);
const newTrace = prop.setImmutable(value);
const newData = update(data, { [traceIndex]: { $set: newTrace } }); Or getting even fancier with const newData = update(data, {
[traceIndex]: {
$apply: (trace) => {
const prop = nestedProperty(trace, attr);
return prop.setImmutable(value);
}
}
});
const newLayout = update(layout, {
xaxis: {
$apply: (xaxis) => {
const prop = nestedProperty(xaxis, attr);
return prop.setImmutable(value);
}
}
}); Or if you want to get vanilla JS again with an array: const trace = data[traceIndex];
const prop = nestedProperty(trace, attr);
const newTrace = prop.setImmutable(value);
const newData = data.slice();
newData[traceIndex] = newTrace; There's other ways to do that last example without mutating, but it's permissible to mutate your own copies as long as you do it in an immutable fashion. |
Sure, I'm just worried that in some of the contexts in which we use |
Well, passing updates back up to the full state tree would be up to the scope that Adding an immutable option to Another alternative solution might be something to generate an object of |
This is basically the same suggestion I've been making internally for a while, so I'm +1 for using The concern I would have is more around situations where right now two disparate bits of plotly.js are essentially communicating using shared references, and this link being broken because one scope is writing to new objects while another scope is reading from a reference to an older, 'orphaned' object. How often does this sort of thing happen, @alexcjohnson ? |
@nicolaskruchten Perhaps you could solve this issue by essentially doubling up on changes during the transition. Create a new immutable update object to send back in callbacks, but then continue to mutate the inputs in the original way for legacy code support? The legacy code (presumably?) would already be ignoring the callback's parameters, but new code can take advantage of them. After that, something like an opt-in e.g.: // Before
const prop = nestedProperty(container, attr);
prop.set(value); // container is mutated
callback();
// After
const prop = nestedProperty(container, attr);
const newContainer = prop.setImmutable(value);
if (!immutableMode) {
prop.set(value); // container is mutated
}
callback(newContainer); |
That might work in cases where the continuation-passing style has been used but will not address the case I'm thinking of where two bits of synchronous code (i.e. no const layout = {a: {b: {c: 1}}};
const closure1 = function() {
const x = layout.a.b;
return (q) => nestedProperty(x, 'c').set(q);
}()
const closure2 = function() {
const y = layout.a.b;
return () => y.c;
}()
for(let i =0; i<5; i++) {
closure1(i);
console.log(closure2());
} The two closures are communicating via shared but inaccessible references ( |
Hi - this issue has been sitting for a while, so as part of our effort to tidy up our public repositories I'm going to close it. If it's still a concern, we'd be grateful if you could open a new issue (with a short reproducible example if appropriate) so that we can add it to our stack. Cheers - @gvwilson |
Related to the immutable mode idea: #2389
While exploring an immutable mode solution for
react-plotly-js-editor
, I noticed a dependency upon Plotly'snestedProperty
.What would be the most ideal way to make an immutable alternative for
nestedProperty
?In a generic scenario the dependency is:
And an alternative immutable API in
nestedProperty
could do this instead:Where
setImmutable
is the same logic asset
(npSet
), but returns an updated copy of the container instead. Under the hood it would use something likeimmutability-helper
to reuse unchanged data when copying.Or would it perhaps be better to create an alternative library file? For example:
Which would be an immutable conversion of
npSet
(usingimmutability-helper
). The downside of this approach is that it might create a code fork between it andnestedProperty
.The text was updated successfully, but these errors were encountered: