Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

question: ng-redux and immutable #101

Open
ipassynk opened this issue Aug 7, 2016 · 7 comments
Open

question: ng-redux and immutable #101

ipassynk opened this issue Aug 7, 2016 · 7 comments

Comments

@ipassynk
Copy link

ipassynk commented Aug 7, 2016

I am using ng-redux with angular 1 application and my store does not use immutable.js at this moment. I am wondering how to make the store immutable and do affect the performance with toJS calls in the controller. I especially concert with calling toJS on each store update in mapStateToProps function. I saw the in react community people use reselect to solve similar concerns. I am wondering if reselect can be also used with ng-redux?

As alternative I am currently playing with idea to use _.memoize in my mapToState function to check if specific slice on store in immutable store has been changed. I am wondering if somebody already use immutable.js with angular 1 and how?

//Let say i have the following store 
let state = Immutable.fromJS({categories: {1: 'a',2: 'b'},links: [1,2,3]});

// my component has binding only to categories sub-store in html view
let key = 'categories';

// mapStateTpProp will call toJS ONLY then category has been changed.
let shouldBindingUpdate = _.memoize((sliceObj, fn) => fn());
function mapStateTpProp(state) {
 return shouldBindingUpdate(state.get(key), () => {
   console.log('toJS called');
   return state.getIn([key]).toJS()
 });
}

//  the first time mapStateTpProp is called and toJS is called
mapStateTpProp(state);

// links subtree has been changed and therefore toJS should not be called since the component cares only about 'categories'
state = state.setIn(['links', '1'], 10);
mapStateTpProp(state);

// reducer changes categories substate in the store and toJS should be called to update view
state = state.setIn(['categories', '1'], 'new Value');
mapStateTpProp(state);
@wbuchwalter
Copy link
Member

Hey,
I haven't used immutable.js personnaly (I was primarily using typescript, which doesn't plays well with immutable.js), so I can't really tell about performance issues.
That said, Reselect can totally be used with ng-redux, I used it extensively.
You use it the same way you would in React.
Here is an old example (in Typescript).
This other somewhat old example uses immutable.js.

Closing the issue, but let me know if that doesn't answer your questions.
Thanks

@ipassynk
Copy link
Author

ipassynk commented Aug 9, 2016

Thanks. I see that reselect is used but i don't think the example app shows a way to use immutable in PROD application. Even the comment says :
"For clarity of the examples, we are doing toJS/fromJS within the reducer
so our component code is easier to follow, and only using immutableJS
here to provide an easy way to do updates to our collection in an
immutable fashion"
.
It is too expensive to do toJS and fromJS in reducers and i am trying to find a way to use immutable and get best of immutable.js smart structural sharing and angular digest.

@wbuchwalter
Copy link
Member

Why don't you do like what is done in react + redux?
Considering that reselect works as well in angular than in react?
I don't understand what's missing there.

Again, I have never used immutable.js in a prod application myself, so sorry for the dumb questions :)

@ipassynk
Copy link
Author

ipassynk commented Aug 9, 2016

As I see how react uses immutable with redux - they try not to perform toJS expensive operation but use immutable collection in JSX. Since all immutable collections are Iterable and have filter, map... API, you can use them directly in JSX without going though very expensive toJS operation that deeply copies the whole store to plain javascript. In immutable.js if a subtree has not been changed after setIn, merge operations, immutable.js will reuse the sub-tree in a new obj. By checking the old ref with new ref you can figure out if sub-tree has been changed (like angular 2 on Push detection) and go via render only when it is needed. If we use toJS - this is completely new object and we loose benefits of immutable and the app performance gets decreased.

@wbuchwalter wbuchwalter reopened this Aug 9, 2016
@wbuchwalter
Copy link
Member

Thanks for the clarification.
Reopening this issue in case someone has some insights to share.
Sorry for not being able to help you more on this one :)

@jasonaden
Copy link

@ipassynk Are you using selectors? Or reselect library? If so, just do the toJs in the selector. If you're using reselect, the toJs method will only run when there is a change to the data. So you can use immutable in your reducers but deal with POJOs in your app.

@hangzho
Copy link

hangzho commented Aug 6, 2017

Recently, I was playing around with ng-redux, immutable and reselect. I post the link here https://github.com/johanzhou8/ng-redux/tree/master/examples/async-immutable in case someone needs the example.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants