-
Notifications
You must be signed in to change notification settings - Fork 208
Fixed nested themes not being republished on outer theme changes #363
Conversation
Codecov Report
@@ Coverage Diff @@
## master #363 +/- ##
=====================================
Coverage 100% 100%
=====================================
Files 10 10
Lines 178 179 +1
Branches 50 50
=====================================
+ Hits 178 179 +1
Continue to review full report at Codecov.
|
f96a56a
to
a904c67
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks fine (and awesome, thanks!), but I'm least comfortable with the theme code in this project. I didn't develop it myself, I rarely use it, and I'm not certain I understand all the use cases. So I'd really like someone who uses glamorous's ThemeProvider
to give this a review as well. Thanks!
@@ -53,13 +58,12 @@ class ThemeProvider extends React.Component { | |||
// set broadcast state by merging outer theme with own | |||
if (this.context[CHANNEL]) { | |||
this.setOuterTheme(this.context[CHANNEL].getState()) | |||
this.broadcast.setState(this.getTheme()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you explain why this was removed? It seems unrelated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
publishTheme method is doing a setState and setOuterTheme uses now publishTheme under the hood
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is the real fix, and publishTheme
is only incidentally changed.
This line was setting the state with no argument, which defaults to the props.theme
here
glamorous/src/theme-provider.js
Line 21 in cb6de3a
const theme = passedTheme || this.props.theme |
A lot of the theming work was done by @vesparny, so if I'm wrong hopefully he can correct me. 😄
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, this part of defaulting to this.props.theme
is a making a control flow a little bit iffy but I left this part untouched. Personally I would prefer explicit arguments, so that publishTheme
would always have to receive getTheme
's result as argument which in turn would always be called with this.props.theme
if necessary.
Also I've noticed a different small issue too - broadcast is initialized as:
broadcast = brcast(this.props.theme)
but that gives it untrue initialState in case of nested ThemeProvider. I think creation of the broadcast
should be delayed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
but that gives it untrue initialState in case of nested ThemeProvider. I think creation of the broadcast should be delayed.
I'm pretty sure I follow, but to be clear, are you suggesting moving it to something like componentWillMount
? With this PR, the theme that was (possibly) merged with the outer theme is now going to be set properly inside componentWillMount()
, so that untrue initial state won't really ever be in effect.
Did I follow your point correctly? If not any clarification would be great. 🙌
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, that was exactly my point :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool, thanks! It makes sense to me. Maybe you want to do that as a follow-up PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure thing, would prefer to create it once we settle on this one to avoid potential conflicts
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the discussion here!
@kentcdodds do u have any other reviewer in mind? The chane is pretty straightforward and the codebase is tested so it shouldnt break anything ;) |
} | ||
} | ||
|
||
componentWillReceiveProps(nextProps) { | ||
if (this.props.theme !== nextProps.theme) { | ||
this.broadcast.setState(this.getTheme(nextProps.theme)) | ||
this.publishTheme(nextProps.theme) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pardon my ignorance, but how has this made an effectual change? publishTheme
is calling broadcast.setState(this.getTheme(nextProps.theme))
which is was was here before. It's only been moved to a separate method.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh, this part is actually not a fix of any sorts, i just have extracted it to separate method so it would be easier to reuse it in setOuterTheme
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, thanks for clarifying.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Super! Thank you for your help!
@@ -53,13 +58,12 @@ class ThemeProvider extends React.Component { | |||
// set broadcast state by merging outer theme with own | |||
if (this.context[CHANNEL]) { | |||
this.setOuterTheme(this.context[CHANNEL].getState()) | |||
this.broadcast.setState(this.getTheme()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the discussion here!
What:
This fixes a bug when having nested
ThemeProvider
s and updating outer theme the change is not reaching theStyledComponent
Why:
This is a bug fix.
How:
Using publish in the nested
ThemeProvider
s subscriptions.Checklist:
Repro provided by @mitchellhamilton - https://codesandbox.io/s/6j42qx5z23