rtfeldman / seamless-immutable

Immutable data structures for JavaScript which are backwards-compatible with normal JS Arrays and Objects.
BSD 3-Clause "New" or "Revised" License
5.37k stars 195 forks source link

Best way to mutate immutables? #103

Closed ablakey closed 8 years ago

ablakey commented 8 years ago

ImmutableJS sucked becauase of its overly verbose way to access data. But it had nice mutators.

If I'm using it properly, seamless-immutable relies on what methods return a new value, so we're missing a lot of how to mutate data. Is there a cleaner way to push a new element onto an array? Currently I'm doing something like this:

    let updatedArray = this.state.arr.asMutable();
    updatedArray.push(newElement);
    this.setState({arr: new Immutable(updatedArray)});
tad-lispy commented 8 years ago

I know it only answers to the specific case in your example, but how about:

this.setState({arr: this.state.arr.concat(newElement)})

Read more about concat at MDN.

kelly-kellerheikkila commented 8 years ago

Arrays are more difficult to work with using seamless-immutable than objects. I basically have to push new elements to immutable arrays using the approach @ablakey describes. It would be great if seamless-immutable supported something like push() and delete() with arrays, just like it does with set() and without() for objects. At this point, I am forced to convert them to mutables for those objects, and then reconvert back to immutable.

tad-lispy commented 8 years ago

That's true, that delete would be useful, however the name doesn't seem safe - it can easily collide with reserved keyword. I would actually call it without.

In one of my projects I came up with this helper function:

remove_item = function(index, array) {
    return array.slice(0, index).concat(array.slice(index + 1));
};

Then you can remove 3rd item by calling:

arr = remove_item(2, arr)

I can make a PR to use it as a method of immutable array. What do you think, @rtfeldman ?

As for the push - is there anything wrong with concat?

rtfeldman commented 8 years ago

Hm, yeah I can't say I'm on board with the idea of adding a redundant concat - I'd definitely recommend using concat for this!

ablakey commented 8 years ago

To respond to the original suggestion: for adding to an array, yes concat works. I wasn't aware of it here and I'm happy with it.

The conversation has mutated (hah!) to talking about other methods for arrays, so I'd like to +1 adding some methods that compensate for the fact that most of the valuable methods in Array.prototype mutate and are therefore not supported with seamless-immutable.

.without() and maybe set() Are at the top of my wish list.

For example, I want to delete a record from a list. I have to make the array mutable, remove it, then make the array immutable again.

Happy to contribute if this is something you want to pursue.

rtfeldman commented 8 years ago

Cool - this seems like a good resolution; I'm gonna close this issue, but feel free to open another to discuss specific feature requests!

slashwhatever commented 7 years ago

Did this ever get implemented or discussed?