"RangeError: Maximum call stack size exceeded" error when updating state in Redux reducer with recursive data structure

163 views Asked by At

I'm encountering an issue while working with a tree view component in my TypeScript application. The elements in the tree are stored in Redux store using the following node structure:

export interface node{
    items: node[], //children nodes
    hasChildren: boolean,
    parent: node| null, // reference to the parent node 
    isActive: boolean,
    elementType: string,
    model: string,
    version: string,
    rdns: Rdn,
    expanded?: boolean
} 

The initial state is as follows:

interface NetworkState {
    networkElements: Node;
}

const initialState: NetworkState = {
    networkElements : networkRoot // Empty root node without children
};

I have successfully implemented a nodeExpanded reducer that expands the selected node, by adding new elements retrieved from an API call. The reducer uses a function to convert the API response into node objects and appends them to the appropriate parent node.

nodeExpanded: (state, action: PayloadAction<{ elementToAdd : MoProxy[],  selectedNode: Node}>) => {
  const {selectedNode, elementToAdd} = action.payload;
  let targetNode = findNode(state.networkElements, selectedNode);
  if (targetNode){
    targetNode.items = convertMoProxiesToNodes(elementToAdd, targetNode);
    targetNode.expanded = true;
  }             
}

Im trying to add another reducer called searchNetworkObject, which also converts an API call response to a Node object and replaces child root nodes with the new elements. Here's the code: :

searchNetworkObject : (state, action: PayloadAction<{treeItem :TreeItemProxy, targetDn: DNProxy[]}>) => {
            const newNode = convertItemToNode(action.payload.treeItem, state.networkElements);
            state.networkElements.items = newNode.items;
        }

The convertItemToNode function recursively creates a new Node based on the TreeItemProxy object. the new node is successfully created, however, when attempting to update the state with the new Node items, I receive the following error from Immer:

common.ts:90  Uncaught (in promise) RangeError: Maximum call stack size exceeded
at common.ts:90:1
at Array.forEach (<anonymous>)
at i (common.ts:90:1)
at M (finalize.ts:61:1)
at A (finalize.ts:148:1)
at finalize.ts:66:1
at common.ts:93:1
at Array.forEach (<anonymous>)
at i (common.ts:90:1)
at M (finalize.ts:61:1)

I have conducted some tests and found that changing the state with the same Node at the same position works perfectly fine in the nodeExpanded reducer but not in the searchNetworkObject reducer.

I have thoroughly compared the nodeExpanded and searchNetworkObject reducers, ensuring that the conversion logic, assignment of properties, and state updates are similar. However, I'm unable to identify the root cause of the "RangeError: Maximum call stack size exceeded" error in the searchNetworkObject reducer.

Are there any specific considerations or best practices when working with recursive data structures in Redux reducers that might be relevant to this issue? What could be causing the error in the searchNetworkObject reducer despite having similar logic as the working nodeExpanded reducer?

0

There are 0 answers