If we use OnPush
change detection strategy, immutability is helpful to ensure change detection works expectedly.
Problem in Immutable.js
One of the way to enforce immutability is using Immutable.js
. However, using Immutable.js
is not really straightforward. It adds another layer instead of using JS object directly e.g
const apps = List([{ name: 'slack' }, { name: 'skype' }]);
apps.get(0); // { name: 'slack' }
const app = Map({ name: 'slack' });
map.get("name"); // 'slack'
// Using Record if we want to access property directly
const AppRecord = Record({
name: ''
});
class App extends AppRecord {
constructor(props) {
super(props);
}
}
const newApp = new App({ name: 'slack' });
newApp.name; // 'slack'
We have to use get
when using List
and Map
. Using Record
could solve the issue, but if we have a very large object, using Record
will be hard to maintain because we need to create each record per object and it's nested object.
Other issue is about JS compatibility because it needs to use fromJS
and toJS
methods to convert from and to JS object.
I'd say that I'm not a fan of that lib and it makes things more complicated.
Other possible approach I'm thinking of:
TS readonly
+ ESLint immutable
Since Angular using Typescript, let's use Readonly<T>
, ReadonlyArray
to enforce immutability.
Also add this no-mutation
ESLint rule as extra protection https://github.com/jonaskello/eslint-plugin-functional/blob/master/docs/rules/immutable-data.md
is there any better approach?
Thank you
Top comments (2)
To deal with nested plain objects in an immutable way, you can use the
patch
function from the Rimbu immutable collections library (disclaimer: I am the author of this library)Hello, did you find any better approach to the problem ? Or are you satisfy to the second method you mentioned ?