Skip to content

Commit

Permalink
refactor createUseStyles (#1237)
Browse files Browse the repository at this point in the history
  • Loading branch information
bs85 authored and kof committed Dec 28, 2019
1 parent 636bc90 commit 9f7924e
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 94 deletions.
24 changes: 12 additions & 12 deletions packages/react-jss/.size-snapshot.json
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
{
"dist/react-jss.js": {
"bundled": 169853,
"minified": 58651,
"gzipped": 19195
"bundled": 168727,
"minified": 58230,
"gzipped": 19069
},
"dist/react-jss.min.js": {
"bundled": 113177,
"minified": 42042,
"gzipped": 14261
"bundled": 112051,
"minified": 41621,
"gzipped": 14141
},
"dist/react-jss.cjs.js": {
"bundled": 27048,
"minified": 11656,
"gzipped": 3863
"bundled": 25998,
"minified": 11164,
"gzipped": 3739
},
"dist/react-jss.esm.js": {
"bundled": 26086,
"minified": 10821,
"gzipped": 3741,
"bundled": 25036,
"minified": 10329,
"gzipped": 3619,
"treeshaked": {
"rollup": {
"code": 1841,
Expand Down
121 changes: 39 additions & 82 deletions packages/react-jss/src/createUseStyles.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,6 @@ const useEffectOrLayoutEffect = isInBrowser ? React.useLayoutEffect : React.useE

const noTheme = {}

const reducer = (prevState, action) => {
if (action.type === 'updateSheet') {
return action.payload
}
return prevState
}

const createUseStyles = <Theme: {}>(styles: Styles<Theme>, options?: HookOptions<Theme> = {}) => {
const {index = getSheetIndex(), theming, name, ...sheetOptions} = options
const ThemeContext = (theming && theming.context) || DefaultThemeContext
Expand All @@ -42,111 +35,75 @@ const createUseStyles = <Theme: {}>(styles: Styles<Theme>, options?: HookOptions
const context = React.useContext(JssContext)
const theme = useTheme()

const [state, dispatch] = React.useReducer(reducer, null, () => {
const sheet = createStyleSheet({
context,
styles,
name,
theme,
index,
sheetOptions
})

let dynamicRules
let classes
if (sheet) {
if (context.registry) {
context.registry.add(sheet)
}
dynamicRules = addDynamicRules(sheet, data)
classes = getSheetClasses(sheet, dynamicRules)
}

return {
sheet,
dynamicRules,
classes: classes || {}
}
})

useEffectOrLayoutEffect(
const [sheet, dynamicRules] = React.useMemo(
() => {
if (state.sheet) {
const newSheet = createStyleSheet({
context,
styles,
name,
theme,
index,
sheetOptions
})

const newDynamicRules = newSheet ? addDynamicRules(newSheet, data) : null

if (newSheet) {
manageSheet({
index,
context,
sheet: state.sheet,
sheet: newSheet,
theme
})
}

return () => {
const {sheet, dynamicRules} = state

if (!sheet) return

unmanageSheet({
index,
context,
sheet,
theme
})

if (dynamicRules) {
removeDynamicRules(sheet, dynamicRules)
}
}
return [newSheet, newDynamicRules]
},
[state.sheet]
[context, theme]
)

useEffectOrLayoutEffect(
() => {
// We only need to update the rules on a subsequent update and not in the first mount
if (state.sheet && state.dynamicRules && !isFirstMount.current) {
updateDynamicRules(data, state.sheet, state.dynamicRules)
if (sheet && dynamicRules && !isFirstMount.current) {
updateDynamicRules(data, sheet, dynamicRules)
}
},
[data]
)

useEffectOrLayoutEffect(
() => {
if (!isFirstMount.current) {
const newSheet = createStyleSheet({
context,
styles,
name,
theme,
index,
sheetOptions
})
const newDynamicRules = newSheet && addDynamicRules(newSheet, data)
const newClasses = newSheet ? getSheetClasses(newSheet, newDynamicRules) : {}

dispatch({
type: 'updateSheet',
payload: {
sheet: newSheet,
dynamicRules: newDynamicRules,
classes: newClasses
}
})
}
},
[theme, context]
() =>
// cleanup only
() => {
if (sheet) {
unmanageSheet({
index,
context,
sheet,
theme
})
}

if (sheet && dynamicRules) {
removeDynamicRules(sheet, dynamicRules)
}
},
[sheet]
)

const classes = sheet && dynamicRules ? getSheetClasses(sheet, dynamicRules) : {}

// $FlowFixMe
React.useDebugValue(state.classes)
React.useDebugValue(classes)
// $FlowFixMe
React.useDebugValue(theme === noTheme ? 'No theme' : theme)

React.useEffect(() => {
isFirstMount.current = false
})

return state.classes
return classes
}
}

Expand Down

0 comments on commit 9f7924e

Please sign in to comment.