-
Notifications
You must be signed in to change notification settings - Fork 50
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
Should not create a new object if the values are the same #20
Comments
That's exactly the intended behaviour. If you don't want a new object to be created, just chain the
|
Maybe I didn't explain very well, that was an oversimplified example. The above code is happening inside an animation loop. A more accurate example would be: getAnimationState(oldAnimationState) {
const newAnimationState = immutable(oldAnimationState);
this.tweens.forEach(tween => newAnimationState.set(tween.path, tween.value));
return newAnimationState.value();
}
Can easily fix with: getAnimationState(oldAnimationState) {
const newAnimationState = immutable(oldAnimationState);
this.tweens.forEach(tween => {
const oldValue = objectPath.get(oldAnimationState, tween.path);
if(oldValue !== tween.value) {
newAnimationState.set(tween.path, tween.value);
}
});
return newAnimationState.value();
} But I was expecting this to be handled internally. Only realised that wasn't the case when I was doing performance profiling. Seems like if both objects deep equal each other then they should be the same reference. To summarise, if all the tween values are the same between frames, I was expecting |
If it makes any difference to you, I just tested and import update from 'immutability-helper';
const obj = { foo: 0 };
const one = update(obj, { foo: { $set: 1 } });
const two = update(one, { foo: { $set: 1 } });
one === two
// true |
Thanks for the more detailed description. I get it now and it makes sense. We'll track this as an enhancement as it's going to change the current behaviour of a few methods. |
No probs, I'm pretty busy atm with paid work but happy to submit a PR for this when I've got some free time. |
FWIW Immutable.js behaves the same const { Map } = require('immutable');
const map = Map({ a: 1 });
console.log(map === map.set('a', 1));
//true
console.log(map.set('a', 1) === map.set('a', 1));
//true I agree that the behavior should be the same and that every operation that can be a noop should be a noop. My non-pseudo code use-case looks like this and I'd love to not have to check each property individually (which are controlled input elements) but compare the immutable instances let changedStory = immutable(this.props.story)
.set('title', this.state.title)
.set('description', this.state.description)
.set('language', this.state.language)
.value();
if(changedStory !== this.props.story) {
this.props.editor.onStoryChange(changedStory);
} |
Was looking through the code and came to the conclusion that it is non-trivial at least for someone not comfortable with the code base. The problem is that the code works top-down and clones all objects along the path, but only at the very end inside So how do we peek at the bottom to see if it would be a noop without duplicating most of the walking-logic? Or how do we delay/schedule the cloning until that point? |
I'm not sure if this is a bug or if I'm misunderstanding how this is supposed to work.
I assumed in the following example
one
andtwo
would be the same object.The text was updated successfully, but these errors were encountered: