Skip to content
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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Iterating over a Set can cause mutations to be ignored #586

Closed
2 tasks done
matchu opened this issue Apr 25, 2020 · 5 comments 路 Fixed by #603
Closed
2 tasks done

Iterating over a Set can cause mutations to be ignored #586

matchu opened this issue Apr 25, 2020 · 5 comments 路 Fixed by #603

Comments

@matchu
Copy link

matchu commented Apr 25, 2020

馃悰 Bug Report

It seems that iterating over Immer's draft of a Set can cause mutations to be ignored. This seems to only happen when you iterate over the set before performing any mutations.

Link to repro

Here's a runnable code sample: https://runkit.com/matchu/5ea3a4b828ff10001bb538ea

const {produce, enableMapSet} = require("immer");
const {expect} = require("chai");

enableMapSet();

let set = new Set([1, 2]);
expect(Array.from(set).sort()).to.eql([1, 2]);

// If we just add to the set, it works!
set = produce(set, draftSet => {
    draftSet.add(3);
});
expect(Array.from(set).sort()).to.eql([1, 2, 3]);

// And we can safely iterate over the set between changes,
// and changes before and after will be applied correctly.
set = produce(set, draftSet => {
    draftSet.add(4);
    console.log("By the way, the set is ", Array.from(draftSet));
    draftSet.add(5);
});
expect(Array.from(set).sort()).to.eql([1, 2, 3, 4, 5]);

// But if we iterate over the set *before* making any changes,
// then all of our changes are ignored.
//
// This test case fails in Immer 6.0.3.
set = produce(set, draftSet => {
    console.log("By the way, the set is ", Array.from(draftSet));
    draftSet.add(6);
});
expect(Array.from(set).sort()).to.eql([1, 2, 3, 4, 5, 6]);

console.log("Done!");

To Reproduce

  1. Enable Immer's MapSet plugin.
  2. Use a produce function over the Set, which iterates over the content of the draft set and then mutates it.

Observed behavior

Mutations made to the draft Set during produce are not reflected in its return value.

Expected behavior

Mutations made to the draft Set during produce would be reflected in its return value, just as if I had not performed iteration before attempting mutation.

Environment

  • Immer version: 6.0.3
  • Occurs with setUseProxies(true)
  • Occurs with setUseProxies(false) (ES5 only)
@matchu
Copy link
Author

matchu commented Apr 25, 2020

For now I'm going to work around this by adding a fake mutation near the start of my producer:

draftSet.add("fake-value-immer#586").delete("fake-value-immer#586");

@mweststrate
Copy link
Collaborator

Confirmed, thanks for the extensive report!

@aleclarson
Copy link
Member

馃帀 This issue has been resolved in version 6.0.7 馃帀

The release is available on:

Your semantic-release bot 馃摝馃殌

@matchu
Copy link
Author

matchu commented May 23, 2020

Thank you!!

@aleclarson
Copy link
Member

馃帀 This issue has been resolved in version 7.0.0 馃帀

The release is available on:

Your semantic-release bot 馃摝馃殌

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants