Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NGRX with Immutable.js

As per answer on Ngrx store immutable state with an array? question, maxime1992 states that he wouldn't recommend to use Immutable.js together with ngrx.

I know using Immutable.js together with redux is a wide spread and normal practice in order to enforce immutability on store changes, but why wouldn't someone want to do exactly the same on Angular applications. Library's supposed to handle immutable data changes much better than spread operator.

So what are cons of using Immutable.js together with ngrx?

like image 984
Evaldas Buinauskas Avatar asked May 25 '18 03:05

Evaldas Buinauskas


1 Answers

I can maybe try to give more info :)

I know using Immutable.js together with redux is a wide spread and normal practice

I'd like to see a trending chart of that. I bet that since ES6 numbers are not going up.

When the immutability pattern started to spread in frontend world few years ago, many people weren't used to it. So Immutable.js was great to hide the "complexity" behind immutability and deal only with well known structures, in a very optimised way.

Also, when I've started a huge Angular project a year and a half ago, I had to make a decision to either use Immutable.js or not. I've decided to go for it because it seems that the performance were incredible. Angular cli generate projects with Typescript (and I'm glad it does!). But few weeks later I've noticed that Immutable.js was really not playing well with Typescript (maybe it did change in the meantime, honnestly can't tell as I've never used it again). And I'd rather prefer to have a well typed code rather than having a lib dealing about immutability for me. So after 2 months of dev, I've decided to make a huuuuge refactor and remove immutablejs to use mostly pure JS (map, filter, they return new references).

If you take for example the following (from immutablejs website):

import Immutable from require('immutable');
var map1: Immutable.Map<string, number>;
map1 = Immutable.Map({a:1, b:2, c:3});
var map2 = map1.set('b', 50);
map1.get('b'); // 2
map2.get('b'); // 50

If you decide to rename a part of your store, good luck to find all the references with something like: map1.get('b');

Whereas with pure JS you'll have no problem at all and Typescript will thrown an error if you forget to rename one.

It's true that I've ended up with plenty of spread objects around my codebase and even if if found it to be very easily readable, well that was "boilerplate".

Now, speaking of ngrx, they make a really nice lib to deal with most of that problem, called @ngrx/entity.

About perfs, I've been working on two huge apps and there's been no problem about that. Especially since the release of the createSelector function which apply memoization to avoid re-computing all the selector every time the store changes.

So when you say

Library's supposed to handle immutable data changes much better than spread operator.

I'd say that you shouldn't worry at all. Really. Try by yourself, create a Stackblitz and try to write a little test/benchmark with a lot of objects, that you add/update all the time. I've done that with extremely large set of array/objects few months ago and it was totally fine.

In conclusion, biggest problem is type inference. But it's also that you just don't need it in my opinion. If you're afraid to miss something regarding immutability, you should just use in dev mode https://www.npmjs.com/package/ngrx-store-freeze which will throw an error if you try to mutate an object from the store.

like image 125
maxime1992 Avatar answered Sep 23 '22 14:09

maxime1992