Use ImmutableJs Records as immutable Objects
When you use Objects, updating them is far from trivial. You can simply set their properties, but that would introduce side effects, and if you want to avoid it, defensive copying is required:
const userObj = {
name: "user1",
score: 10,
};
const updateScore = (user, newScore) => {
return Object.assign({}, user, {score: newScore});
}
console.log(updateScore(userObj, 15)); // {"name":"user1","score":15}
console.log(userObj); // {"name":"user1","score":10}
The Object.assign({}, old, {...properties})
structure returns a new Object that has all properties copied from the original object with some properties overwritten, but it is too verbose.
A better way is to use ImmutableJs's Record. It provide an immutable structure with optimized persistent sets, and an easy-to-read API:
const userRecord = Immutable.Record({
name: "user1",
score: 10,
})();
const updateScore = (user, newScore) => {
return user.set("score", newScore);
}
console.log(updateScore(userRecord, 15)); // {"name":"user1","score":15}
console.log(userRecord); // {"name":"user1","score":10}
You'll need to look out for is how to contruct them. The first call makes a RecordFactory with the initial values, and the second one returns the actual Record instance.
Also, they have a fixed set of potential properties that you set when you create the RecordFactory. Don't be surprised if you add a new property but it is still undefined. Just also add it to where you construct the Record in the first place.
They also support deep updating ImmutableJs structures, making working with nested ones a breeze.