7 ms·
We just use Immutable.js in our Redux stores. Then, using PureRenderMixin is trivial. You just need to be careful not to use the vanilla reducer composer from R
by danmaz74 11y ago
We just use Immutable.js in our Redux stores. Then, using PureRenderMixin is trivial. You just need to be careful not to use the vanilla reducer composer from Redux.
- masklinn 11y agoDepending on the situation, using PureRenderMixin may be less efficient than an immutable-targeted render mixin as it checks for identity not equality. It's easy to hit cases where Immutable collections are equal but not identical (especially when converting from a base state e.g. list.map(func) will create a new list every invocation, but it may create equal lists across invocations). Depending on how often that happens (and thus subsequent extra reconciliations or even re-renders) versus the cost of checking collections for equality (generally O(n), versus O(1) for identity), you may get extra performances from checking for equality.
- danmaz74 11y agoIf there is some slow component where it is worth spending time to do special optimizations, you can use an equality check - or some component-specific check; but my point is that using Immutable and PureRenderMixin by default will speed up lots of situations without having to do any extra work. Moreover, using Immutable is also much less error-prone.
- andrewingram 11y agoThat's only true if you exclusively use Immutable objects for collections and scalars for individual values, if you pass a date as a prop it's not going to work. > new Date(0) === new Date(0) <- false
- masklinn 11y agoThe same problem exists for Immutable collections: > Immutable.List.of(1) === Immutable.List.of(1) < false = $3 which is why Immutable.is exists.
- scotty79 11y agoShould we use Immutable.is instead of == in shouldComponentUpdate() ?
- masklinn 11y agoDepends the semantics you want? `===` is O(1) but it will miss if the collection was altered or replaced in a value-preserving manner, so it will never match if your input is computed (e.g. mapped from a section of the application state). `Immutable.is` is more expensive (since it has to walk both collections) but it will allow skipping updates for equal inputs.
- darklajid 11y agoCan you expand on "You just need to be careful not to use the vanilla reducer composer from Redux." a bit more? Is that 'combineReducers' from Redux? What's wrong with that? What are the alternatives?
- jonesetc 11y agocombineReducers is for taking plain objects and returning another plain object. With immutable you need to either write your own combineReducers or use one that someone else has made that taks immutable objects and returns an immutable object.
- darklajid 11y agoWait - we're talking about the result of the combination? If you follow a 'get started with redux' thing and end up with a root reducer that uses combineReducers: You're talking about the outermost 'state' object? Because any reducer that you write can certainly accept/understand/return immutables, right? If I picked that up correctly: Is that a problem for a single combineReducers at the root? Because if all the properties of that thing are immutable, wouldn't you get the cheap identity based comparison benefits whenever you pass on props.foo in your store-aware component?
- danmaz74 11y agoYes, it's the actual combiner that can't create an Immutable object.
- danmaz74 11y agojonestetc already explained the gist of it - combineReducers expects vanilla javascript objects, not Immutable ones; you can find an example Immutable-compatible implementation here: https://github.com/gajus/redux-immutable https://github.com/gajus/redux-immutable We don't use it though, it's really easy to just create your own version and use that and preferred to have one less dependency.