leoasis / redux-immutable-state-invariant

Redux middleware that detects mutations between and outside redux dispatches. For development use only.
MIT License
937 stars 37 forks source link

Error setting up #15

Closed oyeanuj closed 7 years ago

oyeanuj commented 8 years ago

Hi @leoasis! I was looking to try your library but ran into the following error right away. (Apologies if this is a n00b error)

RangeError: Maximum call stack size exceeded
[1]     at trackProperties (node_modules/redux-immutable-state-invariant/dist/trackForMutations.js:18:3)
[1]     at trackProperties (node_modules/redux-immutable-state-invariant/dist/trackForMutations.js:24:31)

Relevant code setting up:


let middleware = [createMiddleware(client), transitionMiddleware];
  if (__DEVELOPMENT__) {
    const logger = createLogger({
    logger: console
    });

   const immutableState = require('redux-immutable-state-invariant')();
    middleware = [
    createMiddleware(client),
    transitionMiddleware,
    logger,
    immutableState
    ];
  }

  finalCreateStore = applyMiddleware(...middleware)(_createStore);

I am running "redux": "^3.0.5" if that helps diagnose.

Any help would be much appreciated, and thank you for the library!

leoasis commented 8 years ago

Hey! first of all glad that you find this useful! And sorry for taking a bit to respond hehe.

What's the shape of your state? It looks like there may be circular dependencies in your state, which is causing problems with the way we traverse it to track mutations. Remember the state must be serializable in redux.

oyeanuj commented 8 years ago

Thanks for your quick response! My state is a complex object with many normalized entities. So, I think you are right that there are circular references. Is there a way to make this library work with circular dependencies?

leoasis commented 8 years ago

If it's normalized then there shouldn't be any circular references. In general it's not a good practice to have circular references in your state, so that's why I'm wary about adding support for that in this library, especially since this one is about tracking mutations (which disallow circular references since that implies you cannot modify any object that is part of a circular dependency). Is there anything that you could paste or provide hear to better understand the use case and the need to use circular references in the first place?

oyeanuj commented 8 years ago

@leoasis Sorry, I missed your comment above. In my case, the circular reference exists for two reasons -

  1. There are places where the API returns deeply nested objects which have relationships. A post has author but also has comments which also have authors who also have other posts.
  2. To deal with the limitations of normalization and denormalization, I have often had to be creative about what and how to normalize (and then subsequently denormalize) while keeping performance in mind. So there can be cases where choosing not to normalize some nesting might also lead to circular references.

Let me know if the above makes sense, I'd be happy to elaborate more. I understand if circular references make it impossible for the library to perform its duties, but I am sure the above cases are more common (and there might be more).

leoasis commented 8 years ago

There are places where the API returns deeply nested objects which have relationships. A post has author but also has comments which also have authors who also have other posts.

How is this possible? The API should return something that is serializable over the wire, which means it cannot have anything that contains circular dependencies. There must be something after this that is creating this circular dependencies based on the API response.

To deal with the limitations of normalization and denormalization, I have often had to be creative about what and how to normalize (and then subsequently denormalize) while keeping performance in mind. So there can be cases where choosing not to normalize some nesting might also lead to circular references.

I understand this part, but still that doesn't mean you have to have circular dependencies, because of what I said in the point above. An API response over the wire cannot have circular dependencies, because that response must have been serialized, and serialized data cannot have circular dependencies. It can represent references to other places in the json response, but it should just be a tree of data.

Is there any piece of code I could look to so that I can better understand what you need? I think looking at some code will make the situation clear and we can discuss on that.

leoasis commented 7 years ago

Closing since it's been long since this hasn't had answers. Feel free to reopen if you still have issues!

jordaaash commented 7 years ago

I have this issue. While the response from an API may be JSON, it's common for client side deserialization of responses (like an ORM, Relay, etc.) to create relationships between objects. Perhaps the library could warn on discovering a circular reference rather than failing hard? This at least offers the opportunity to determine the location and scope of the reference, which can then possibly be resolved.

leoasis commented 7 years ago

Yes, good idea! that's something that would be good to add to the library, if you want you can send a PR, happy to review it!