Exploring the Relationship Between Redux and ImmutableJS in Managing Nested State and Understanding the Computational Complexity of Immutable

Trying to grasp the concept of Immutability for my debut Redux (NGRX/Store) endeavor has been quite the challenge. Avoiding state mutation has been a struggle, especially while dealing with Object.assign({}) and state mutation errors. Thankfully, I stumbled upon Immutable.JS, which has made my life much easier.

Imagine having a Financial Trading Application that needs to showcase a collection of Bars on a chart upon loading. The last bar must be updated periodically with live price data, and new bars are added intermittently.

All of this must be executed for {1-n} financial instruments (EURUSD/GBPJPY/Gold/Oil etc.). To tackle this aspect of my application, I have come up with the following model:

export interface CandleState {
  LastCompletedCandle : Candle;
  InProgressCandle : Candle;
  LastTick:Offer;
  ClosedCandles:immutable.List<Candle>;
};

export interface AllCandleState {
   instruments: immutable.Map<string, CandleState>
}

It is worth noting that I am utilizing an Immutable Map that contains an Immutable List. My initial question is: Is there a purpose to having 'immutability within immutability' in this scenario? When I call

instruments.set("EURUSD", { [my new state] })

I am essentially receiving an entirely new state, so I am uncertain if nested immutability is necessary. I want to be able to subscribe to changes on the ClosedCandles list; will making it immutable enable direct observation of these changes? Or are changes only detected at the 'top' level?

Another question that arises is: should I be concerned about this at all? I have a notion that altering an immutable collection is a costly operation. If I use list.push or map.set, what exactly occurs behind the scenes? Am I copying every item in the array or map into a new array/map every time a modification is made to an immutable collection? Or is it merely a change in reference?

It would be helpful to have some published information on the Big-Oh Complexity of immutable collections to better understand their performance, but unfortunately, such data seems to be elusive.

Answer №1

Is there any benefit to implementing 'immutability within immutability' like this?

Generally speaking, the simple answer is: No. While immutability does not directly impact change detection, it does reinforce the principle of creating new objects instead of modifying existing states outside the store (or even within the reducer).

I want to be able to track changes in the ClosedCandles list; will making it immutable allow observers to detect changes directly, or are changes only detected from the top level?

The answer is both yes and no. Monitoring changes directly can be achieved by setting up a stream that selects instruments.ClosedCandles - but this functionality is not exclusive to immutability and can be achieved with or without it.

When it comes to immutability and the concept of altering objects from the top down, any changes made multiple levels deep within an object will require recreating all parent objects up to the root. This is because immutable objects cannot be altered, necessitating the creation of new references.

For example:

root                
|--map1             
|  |--set1          
|  \--set2          
|     |--attribute1 
|     \--attribute2 
|
|--map2             
\--map3             

Do I need to be concerned about the performance implications of changing an immutable collection? Is it a costly operation to add items to a list or map within an immutable collection?

The performance impact of mutating immutable collections largely depends on how you implement them. Many libraries optimize these operations and abstract them away from the developer. In most cases, performance won't be significantly affected as only small portions of the state will be modified, with new references being used without creating entirely new objects.

In cases where performance is critical, you can choose to use immutables for development and testing purposes to ensure correctness, then disable immutability for production builds to optimize performance further.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Upgrading from React-Redux version 1.x to version 2.x: The transition you

As a beginner, I have been following tutorials that use an example with React-Redux v1. However, I encountered an issue where my code won't compile and it shows the error message: < Provider > does not support changing store on the fly. It is mo ...

Tips for retrieving the generated ID from the server immediately following form submission using the Post method in TypeScript

When submitting a long-form, it is important to ensure that no data is lost. Users should be able to stay on the same page to make any necessary changes after clicking the submit button. I need to receive the unique id generated by the server upon submissi ...

What is the most efficient way to apply multiple combinations for filtering the information within a table?

I'm facing an issue with my Angular project. I have 4 select boxes that allow users to apply different filters: office worker project name employee activities The problem I'm encountering is the difficulty in predicting all possible combination ...

Issue: formGroup requires an input of type FormGroup. Please provide one; Error: Unable to access property 'controls' as it is undefined

In the process of building a login and registration form using Angular with .Net core, I encountered an error upon running the program. The error is showing up in the Browser Console tab. This is my userlog.component.ts file: import { Component, OnInit, O ...

Every time an action is carried out in the app, React generates countless TypeError messages

Whenever I'm using the application (particularly when started with npm start), my console gets flooded with thousands of TypeError messages like this: https://i.sstatic.net/3YZpV.png This issue doesn't occur when I build the app... It's fr ...

In the given situation, which would be the preferable option - making use of useEffect or opting for

My custom hook fetches data from a smart contract as shown below: export const usePoolLength = () => { const [length, setLength] = useState(0); const _getPoolLength = useCallback(async () => { const poolLength = await getPoolLength() ...

Using Typescript and ThreeJS, include new elements to the environment within the loader

Can someone help me with the following code snippet? export class LandingPageComponent implements OnInit { scene: THREE.Scene; (...) ngOnInit() { this.scene = new THREE.Scene(); var loader = new THREE.JSONLoader(); loader.load("../../assets/fire_lion.j ...

How can I run a TypeScript function within a JavaScript file?

I am working with a typescript file named file1.ts export function Hello(str: string) { console.log(str); } In addition, I have another file called index.js { require('./some.js'); } Furthermore, there is a script defined in the pack ...

Typescript - Keeping a log of object keys along with their corresponding key type values

Imagine having the following scenario where you need to create an object with keys that are transformed versions of the original type's values: export type CCDTypes = { AuthorisationCaseEvent: AuthorisationCaseEvent, AuthorisationCaseField: Author ...

The sum is being treated as a concatenation instead of an addition in this case

Why is the somma value showing the concatenation of totaleEnergetico and totaleStrutturale instead of a sum? RiepilogoCombinatoStComponent.ts export class RiepilogoCombinatoStComponent implements OnInit { constructor() { } interventi: AssociazioneI ...

Observer function simulated by SinonStub

I am currently testing express middleware using sinon.js My goal is to verify that it sends a specific JSON response and prevents the request from moving on to the next middleware or request handler. const middleware = (req: Request, res: Response, nex ...

What is the proper way to declare app.use using TypeScript with the node.js Express module?

I am working on a node.js app that utilizes typescript with express. In my code, I have defined an error middleware function as shown below: app.use((error:any, req:Request, res:Response, next:NextFunction) => { res.status(500).json({message:error.m ...

How should one go about creating and revoking a blob in React's useEffect function?

Consider this scenario: import { useEffect, useState, type ReactElement } from 'react'; async function getImage(): Promise<Blob> { // Some random async code const res = await fetch('https://picsum.photos/200'); const blob = ...

Ways to extend the default timeout duration in Angular

My server calls are taking a long time, around 30-40 minutes, and my Angular frontend is timing out. Is there a way to increase the default timeout for this service call? method1(id: number): Promise<number> { const body= JSON.stringify(id); ...

Error when running end-to-end tests in Angular CLI using the ng e2e

Recently, I created a new Angular 4 project using the Angular CLI. Upon running ng e2e, the sample end-to-end test worked flawlessly. However, when I later added a subfolder named services in the app folder and generated a service within it, the ng e2e com ...

How do I adjust brightness and contrast filters on a base64 URL?

When presented with an image in base64 format like this: data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABDAAwfqNRk/rjcYX+PxrV/wtWqwJSTlboMgAAAABJRU5ErkJggg== What is the most efficient method to programmatically alter a filter (such as brightness or cont ...

Pipe for Angular that allows for searching full sentences regardless of the order of the words

I am looking to create a search bar that can search for the 'title' from the table below, regardless of the word order in the sentence. I attempted to use a filter pipe to check if the search string exists in the title. I also experimented with ...

Error: Code layer not located while utilizing "sam invoke local" in AWS

Currently, I am engaged in an AWS project where I am developing two lambda functions. Both of these functions rely on a common codebase stored in the node_modules directory, which is placed in a separate layer named AWS::Lambda::LayerVersion, not to be con ...

Updating a property in a JavaScript object using Angular

Working with Angular, I have a dataset: export class AppComponent { data = [ { "area1": { "format": "changethis" } ] I am looking to develop a function that can alter the value of a specific key. For e ...

Converting JSON Arrays into Typescript Arrays

I am working with a JSON file that contains an array object like this: [ { "VergiNo": "XXXXXXX" }, { "VergiNo": "YYYYYY" }, { "VergiNo": "ZZZZZZ" } ] After importing this JSON file into my Typescript file, import * as companies f ...