Skip to content

Commit

Permalink
Implement umbrella caching and referential purity for themes.
Browse files Browse the repository at this point in the history
  • Loading branch information
schwers committed Feb 23, 2018
1 parent 68a85c8 commit e0b83b8
Show file tree
Hide file tree
Showing 9 changed files with 356 additions and 203 deletions.
9 changes: 0 additions & 9 deletions jsconfig.json

This file was deleted.

47 changes: 31 additions & 16 deletions src/hoc/withTheme.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,31 +31,46 @@ const wrapWithTheme = (Component: ReactClass<any>) => {
state: { theme?: ?Object } = {};
unsubscribeId: number = -1

componentWillMount() {
constructor(props, context) {
super(props, context)
const { defaultProps } = this.constructor
const styledContext = this.context[CHANNEL_NEXT]
const themeProp = determineTheme(this.props, undefined, defaultProps)
if (styledContext === undefined && themeProp === undefined && process.env.NODE_ENV !== 'production') {
const styledContext = context[CHANNEL_NEXT]
const themeProp = determineTheme(props, undefined, defaultProps)

if (
styledContext === undefined &&
themeProp === undefined &&
process.env.NODE_ENV !== 'production'
) {
// eslint-disable-next-line no-console
console.warn('[withTheme] You are not using a ThemeProvider nor passing a theme prop or a theme in defaultProps')
} else if (styledContext === undefined && themeProp !== undefined) {
this.setState({ theme: themeProp })
this.state = {
theme: themeProp,
}
} else {
const { subscribe } = styledContext
this.unsubscribeId = subscribe(nextTheme => {
const theme = determineTheme(this.props, nextTheme, defaultProps)
this.setState({ theme })
})
const { subscribe, currentTheme } = styledContext
this.state = {
theme: currentTheme(),
}

this.unsubscribeId = subscribe(this.updateTheme)
}
}

componentWillReceiveProps(nextProps: { theme?: ?Object, [key: string]: any }) {
const { defaultProps } = this.constructor
this.setState((oldState) => {
const theme = determineTheme(nextProps, oldState.theme, defaultProps)
updateTheme = nextTheme => {
const theme = determineTheme(this.props, nextTheme, this.constructor.defaultProps)
if (theme !== this.state.theme) {
this.setState({ theme })
}
}

return { theme }
})
componentWillReceiveProps(nextProps: { theme?: Object, [key: string]: any }) {
const { defaultProps } = this.constructor
const theme = determineTheme(nextProps, this.state.theme, defaultProps)
if (theme !== this.state.theme) {
this.setState({ theme })
}
}

componentWillUnmount() {
Expand Down
4 changes: 3 additions & 1 deletion src/models/ComponentStyle.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,9 @@ export default (nameGenerator: NameGenerator, flatten: Flattener, stringifyRules
componentId: string
isStatic: boolean
lastClassName: ?string

lastProps: ?any // let dynamic components do "magic umbrella caching"
// see `StyledComponent.js`
lastTheme: ?any // // let dynamic components do "magic umbrella caching"

constructor(rules: RuleSet, attrs?: Object, componentId: string) {
this.rules = rules
Expand Down
Loading

0 comments on commit e0b83b8

Please sign in to comment.