diff --git a/packages/react-jss/.size-snapshot.json b/packages/react-jss/.size-snapshot.json index fe77f646e..992fb8aae 100644 --- a/packages/react-jss/.size-snapshot.json +++ b/packages/react-jss/.size-snapshot.json @@ -1,30 +1,30 @@ { "react-jss.js": { - "bundled": 136030, - "minified": 50117, - "gzipped": 16723 + "bundled": 77728, + "minified": 28993, + "gzipped": 10122 }, "react-jss.min.js": { - "bundled": 102980, - "minified": 39976, - "gzipped": 13837 + "bundled": 45475, + "minified": 19337, + "gzipped": 7396 }, "react-jss.cjs.js": { - "bundled": 21554, - "minified": 9502, - "gzipped": 3177 + "bundled": 21488, + "minified": 9523, + "gzipped": 3163 }, "react-jss.esm.js": { - "bundled": 19636, - "minified": 8002, - "gzipped": 2959, + "bundled": 19604, + "minified": 8056, + "gzipped": 2958, "treeshaked": { "rollup": { "code": 426, "import_statements": 368 }, "webpack": { - "code": 1945 + "code": 1967 } } } diff --git a/packages/react-jss/src/createUseStyles.js b/packages/react-jss/src/createUseStyles.js index ef8cfb203..34adbb5f7 100644 --- a/packages/react-jss/src/createUseStyles.js +++ b/packages/react-jss/src/createUseStyles.js @@ -13,7 +13,10 @@ import getSheetIndex from './utils/getSheetIndex' import {manageSheet, unmanageSheet} from './utils/managers' import getSheetClasses from './utils/getSheetClasses' -const useEffectOrLayoutEffect = isInBrowser ? React.useLayoutEffect : React.useEffect +const useInsertionEffect = isInBrowser + ? React.useInsertionEffect || // React 18+ (https://github.com/reactwg/react-18/discussions/110) + React.useLayoutEffect + : React.useEffect const noTheme = {} @@ -36,57 +39,53 @@ const createUseStyles = (styles, options = {}) => { const context = React.useContext(JssContext) const theme = useTheme(data && data.theme) - const [sheet, dynamicRules] = React.useMemo(() => { - const newSheet = createStyleSheet({ - context, - styles, - name, - theme, + const sheet = React.useMemo( + () => + createStyleSheet({ + context, + styles, + name, + theme, + index, + sheetOptions + }), + [context, theme] + ) + + const dynamicRules = React.useMemo(() => (sheet ? addDynamicRules(sheet, data) : null), [sheet]) + + useInsertionEffect(() => { + manageSheet({ index, - sheetOptions + context, + sheet, + theme }) - const newDynamicRules = newSheet ? addDynamicRules(newSheet, data) : null - - if (newSheet) { - manageSheet({ - index, - context, - sheet: newSheet, - theme - }) + return () => { + if (sheet) { + unmanageSheet({ + index, + context, + sheet, + theme + }) + + // when sheet changes, remove related dynamic rules + if (dynamicRules) { + removeDynamicRules(sheet, dynamicRules) + } + } } + }, [sheet]) - return [newSheet, newDynamicRules] - }, [context, theme]) - - useEffectOrLayoutEffect(() => { + useInsertionEffect(() => { // We only need to update the rules on a subsequent update and not in the first mount if (sheet && dynamicRules && !isFirstMount.current) { updateDynamicRules(data, sheet, dynamicRules) } }, [data]) - useEffectOrLayoutEffect( - () => - // cleanup only - () => { - if (sheet) { - unmanageSheet({ - index, - context, - sheet, - theme - }) - } - - if (sheet && dynamicRules) { - removeDynamicRules(sheet, dynamicRules) - } - }, - [sheet] - ) - const classes = React.useMemo( () => (sheet && dynamicRules ? getSheetClasses(sheet, dynamicRules) : emptyObject), [sheet, dynamicRules]