Themr breaks shouldComponentUpdate shallow equal optimization
istarkov opened this issue · comments
Themr breaks shouldComponentUpdate shallow equal optimization.
Every new render themr returns a new object reference for theme object, so all subsequent optimizations based on shallowEqual
like pure
recompose enhancer always returns true.
As nextProps.theme !== props.theme
.
I'll create a PR to fix.
Please describe why do you think it's a responsibity of themr
to handle optimizations like pure
-rendering out of the box?
I believe if one has to use objects in props instead of plain values then such cases should be handled explicitly.
IMO nothing is broken here, it's an expected behavior of using shallowEqual
and if you need special behavior you should enhance your shouldComponentUpdate
to handle theme
-objects and to check them deeply.
@raveclassic It's not the responsibility of themr
to handle optimizations, but it should not break the usual components lifecycles if it added.
As it is a enhancer it should not affect component behaviour, so it should not generate a new properties every rerender as it will break optimized component logic.
@istarkov Agree, but it actually is the default behavior - themr HOC
addes an object
to child's props. Why should shallowEqual
ignore this object implicitly?
It is not ignored. The only change here is an optimization allowing not to recalculate theme object if nothing has changed. And a good news this optimization solves other non wide issue
@istarkov Yes, you are right, sorry =)
Well, what about detecting context changes?
I thought about context - the problem that in that case you should implement something like, like in react-router (new) and redux, where you should subscribe on context changes explicitly.
Not sure that it's needed for this small library.
But may be I'm wrong.
(We does not use context for themr
, and not sure that anybody who use it changes it on the fly)
@istarkov But now this.theme_
is composed without context even if pure-rendering is disabled, this is a breaking change then.
Where is no dependency here on pure rendering at all, we can forget word pure.
context is used only if one of three property has changed, and not used in usual rerendering.
From one sight it is a problem, from the other is not, as at current themr
version there is also no mechanism to notify component about that context has changed.
So the only difference that in current themr version some random render will update theme props with context and in this PR some custom render will update theme with context props. I see no difference as both situations are wrong.
I do not state that theme should be updatable by context changes. As you've already pointed it's another problem and it should be solved with the ways like in react-router.
I meant that initial theme composition in constructor and in componentWillReceiveProps
does not take context into account anymore and therefore it's a breaking change.
Why it does not take a context as it is the same source as before? As this.getContextTheme()
was called as it's called now, no difference.
@raveclassic also please look at tests all tests are passed https://github.com/javivelasco/react-css-themr/blob/master/test/components/themr.spec.js
@istarkov Ahh makes sense now, sorry, didn't notice. At last we need to wait @javivelasco to take a look.
Seems like a good library to solve context issues https://github.com/ReactTraining/react-broadcast
Thank you @istarkov and @raveclassic, beautiful conversation 😄 I'm merging 👍 there are no breaking changes and I agree that updating context should not be solved in here. I'm also releasing a patch