Handling big states in reducer #454

Closed
razjel opened this Issue Aug 10, 2015 · 2 comments

Comments

3 participants
@razjel

razjel commented Aug 10, 2015

I'm writing large TypeScript application and my state got quite complex and nested. That's how my example state for particular reducer looks (I know that this can be simplified, but for the sake of my case let's say I need to have such structure, because there will be more parameters):

class AllPhotoData {
  public photoDatas:OrderedMap<string,PhotoData>; //this class works similiar to ES6 Map, but it also remebers order in which items were added
}
class PhotoData {
  hash:string;
  mimetype:string;
  printParams:PrintParams;
}
class PrintParams {
  size:string;
  paper:string;
}

When I want to change property size in reducer, do I need to create new instance of each object above last param, which would look sth like this:

case "UPDATE_SIZE":
  //clone() - returns shallow copy
  state.photoDatas = state.photoDatas.clone();
  state.photoDatas.replace(state.photoDatas.get(action.hash).clone());
  state.photoDatas.get(action.hash).printParams = state.photoDatas.get(action.hash).printParams.clone();
  state.photoDatas.get(action.hash).printParams.size = action.newSize;
  return state;

or is it enough to update only parent object which contains changed data?

case "UPDATE_SIZE":
  state.photoDatas.get(action.hash).printParams = state.photoDatas.get(action.hash).printParams.clone();
  state.photoDatas.get(action.hash).printParams.size = action.newSize;
  return state;

@gaearon gaearon added the question label Aug 10, 2015

@gaearon

This comment has been minimized.

Show comment
Hide comment
@gaearon

gaearon Aug 10, 2015

Collaborator

do I need to create new instance of each object above last param

Yes.

or is it enough to update only parent object which contains changed data?

No.

If you change something deeply, you need to change the reference to change at every level upwards. This is why using custom classes for Redux state isn't a very good idea.

If you often need to change state deeply and you are concerned about performance, use Immutable.js which utilizes structural sharing for minimal memory overhead on deep changes. It also has nice APIs like mergeDeep() to help with this.

Collaborator

gaearon commented Aug 10, 2015

do I need to create new instance of each object above last param

Yes.

or is it enough to update only parent object which contains changed data?

No.

If you change something deeply, you need to change the reference to change at every level upwards. This is why using custom classes for Redux state isn't a very good idea.

If you often need to change state deeply and you are concerned about performance, use Immutable.js which utilizes structural sharing for minimal memory overhead on deep changes. It also has nice APIs like mergeDeep() to help with this.

@gaearon gaearon closed this Aug 10, 2015

@gaearon gaearon changed the title from Handling big states in reductor to Handling big states in reducer Aug 10, 2015

@cesarandreu

This comment has been minimized.

Show comment
Hide comment
@cesarandreu

cesarandreu Aug 11, 2015

Contributor

@razjel to add a bit to what @gaearon said, one feature of immutable.js that you should be aware of is withMutations. It lets you perform multiple changes (which you typically want to do in your reducers) without having to create an intermediate object for each, so the memory cost is reduced even further.

Contributor

cesarandreu commented Aug 11, 2015

@razjel to add a bit to what @gaearon said, one feature of immutable.js that you should be aware of is withMutations. It lets you perform multiple changes (which you typically want to do in your reducers) without having to create an intermediate object for each, so the memory cost is reduced even further.

@jameslk jameslk referenced this issue in reduxjs/react-redux Nov 13, 2015

Closed

Using custom objects in state #187

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment