Skip to content

Instantly share code, notes, and snippets.

@arniebradfo
Last active January 29, 2024 14:33
Show Gist options
  • Save arniebradfo/dc1dcb0793108cfc4cfca8faf0cb15d3 to your computer and use it in GitHub Desktop.
Save arniebradfo/dc1dcb0793108cfc4cfca8faf0cb15d3 to your computer and use it in GitHub Desktop.

Revisions

  1. arniebradfo revised this gist May 1, 2021. 1 changed file with 0 additions and 87 deletions.
    87 changes: 0 additions & 87 deletions test.tsx
    Original file line number Diff line number Diff line change
    @@ -1,87 +0,0 @@
    import { useEffect } from 'react'

    // global list of all the StyleSheets that are touched in useDisableImportedStyles
    const switchableGlobalStyleSheets: StyleSheet[] = []

    // just to clarify what createUseDisableImportedStyles() returns
    type useDisableImportedStyles = () => void

    /**
    * Conditionally apply imported .css files
    * WARNING: This is pretty finicky. You must set this up exactly or there may be unintended consequences
    *
    * ## Conditions:
    *
    * 1. `createUseDisableImportedStyles` must called in global scope in the same tsx file as the imported css being targeted and the component to be lazy loaded
    * ```tsx
    * import React from 'react'
    * import { createUseDisableImportedStyles } from './useDisableImportedStyles'
    * import './global-styles.css'
    * const useDisableImportedStyles = createUseDisableImportedStyles()
    * export const CssComponent: React.FC<{}> = () => {
    * useDisableImportedStyles()
    * return null
    * }
    * export default CssComponent
    * ```
    *
    * 2. A component using this hook *should* be lazy loaded:
    * ```tsx
    * LazyCssComponent = React.lazy(() => import('./cssComponent'))
    * ...
    * <React.Suspense fallback={<></>}>
    * {condition && <LazyCssComponent/>}
    * </React.Suspense>
    * ```
    * - An exception to lazy loading might be using this in a single, normal, non-lazy component so styles are loaded on first render
    * - NOTE: the `InitialCssComponent` never needs to actually render, it just needs to be imported
    * - BUT: this will only work if there is **one single** .css file imported globally, otherwise, I don't know what would happen
    * ```tsx
    * import InitialCssComponent from './initialCssComponent'
    * LazyCssComponent = React.lazy(() => import('./cssComponent'))
    * ...
    * {false && <InitialCssComponent/>}
    * <React.Suspense fallback={<></>}>
    * {condition && <LazyCssComponent/>}
    * </React.Suspense>
    * ```
    *
    * @param {boolean} immediatelyUnloadStyle
    * if true: immediately unloads the StyleSheet when the component is unmounted
    * if false: waits to unloads the StyleSheet until another instance of useDisableImportedStyles is called. This avoids a flash of unstyled content
    *
    */
    export const createUseDisableImportedStyles = (
    immediatelyUnloadStyle: boolean = true
    ): useDisableImportedStyles => {
    let localStyleSheet: StyleSheet
    return () => {
    useEffect(() => {

    // if there are no stylesheets, you did something wrong...
    if (document.styleSheets.length < 1) return

    // set the localStyleSheet if this is the first time this instance of this useEffect is called
    if (localStyleSheet == null) {
    localStyleSheet = document.styleSheets[document.styleSheets.length - 1]
    switchableGlobalStyleSheets.push(localStyleSheet)
    }

    // if we are switching StyleSheets, disable all switchableGlobalStyleSheets
    if (!immediatelyUnloadStyle) {
    switchableGlobalStyleSheets.forEach(styleSheet => styleSheet.disabled = true)
    }

    // enable our StyleSheet!
    localStyleSheet.disabled = false

    // if we are NOT switching StyleSheets, disable this StyleSheet when the component is unmounted
    if (immediatelyUnloadStyle) return () => {
    if (localStyleSheet != null) localStyleSheet.disabled = true
    }

    })
    }
    }

    // GOOD LUCK !
  2. arniebradfo revised this gist May 1, 2021. 1 changed file with 87 additions and 0 deletions.
    87 changes: 87 additions & 0 deletions test.tsx
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,87 @@
    import { useEffect } from 'react'

    // global list of all the StyleSheets that are touched in useDisableImportedStyles
    const switchableGlobalStyleSheets: StyleSheet[] = []

    // just to clarify what createUseDisableImportedStyles() returns
    type useDisableImportedStyles = () => void

    /**
    * Conditionally apply imported .css files
    * WARNING: This is pretty finicky. You must set this up exactly or there may be unintended consequences
    *
    * ## Conditions:
    *
    * 1. `createUseDisableImportedStyles` must called in global scope in the same tsx file as the imported css being targeted and the component to be lazy loaded
    * ```tsx
    * import React from 'react'
    * import { createUseDisableImportedStyles } from './useDisableImportedStyles'
    * import './global-styles.css'
    * const useDisableImportedStyles = createUseDisableImportedStyles()
    * export const CssComponent: React.FC<{}> = () => {
    * useDisableImportedStyles()
    * return null
    * }
    * export default CssComponent
    * ```
    *
    * 2. A component using this hook *should* be lazy loaded:
    * ```tsx
    * LazyCssComponent = React.lazy(() => import('./cssComponent'))
    * ...
    * <React.Suspense fallback={<></>}>
    * {condition && <LazyCssComponent/>}
    * </React.Suspense>
    * ```
    * - An exception to lazy loading might be using this in a single, normal, non-lazy component so styles are loaded on first render
    * - NOTE: the `InitialCssComponent` never needs to actually render, it just needs to be imported
    * - BUT: this will only work if there is **one single** .css file imported globally, otherwise, I don't know what would happen
    * ```tsx
    * import InitialCssComponent from './initialCssComponent'
    * LazyCssComponent = React.lazy(() => import('./cssComponent'))
    * ...
    * {false && <InitialCssComponent/>}
    * <React.Suspense fallback={<></>}>
    * {condition && <LazyCssComponent/>}
    * </React.Suspense>
    * ```
    *
    * @param {boolean} immediatelyUnloadStyle
    * if true: immediately unloads the StyleSheet when the component is unmounted
    * if false: waits to unloads the StyleSheet until another instance of useDisableImportedStyles is called. This avoids a flash of unstyled content
    *
    */
    export const createUseDisableImportedStyles = (
    immediatelyUnloadStyle: boolean = true
    ): useDisableImportedStyles => {
    let localStyleSheet: StyleSheet
    return () => {
    useEffect(() => {

    // if there are no stylesheets, you did something wrong...
    if (document.styleSheets.length < 1) return

    // set the localStyleSheet if this is the first time this instance of this useEffect is called
    if (localStyleSheet == null) {
    localStyleSheet = document.styleSheets[document.styleSheets.length - 1]
    switchableGlobalStyleSheets.push(localStyleSheet)
    }

    // if we are switching StyleSheets, disable all switchableGlobalStyleSheets
    if (!immediatelyUnloadStyle) {
    switchableGlobalStyleSheets.forEach(styleSheet => styleSheet.disabled = true)
    }

    // enable our StyleSheet!
    localStyleSheet.disabled = false

    // if we are NOT switching StyleSheets, disable this StyleSheet when the component is unmounted
    if (immediatelyUnloadStyle) return () => {
    if (localStyleSheet != null) localStyleSheet.disabled = true
    }

    })
    }
    }

    // GOOD LUCK !
  3. arniebradfo revised this gist May 1, 2021. 1 changed file with 2 additions and 0 deletions.
    2 changes: 2 additions & 0 deletions useDisableImportedStyles.tsx
    Original file line number Diff line number Diff line change
    @@ -83,3 +83,5 @@ export const createUseDisableImportedStyles = (
    })
    }
    }

    // GOOD LUCK !
  4. arniebradfo revised this gist May 1, 2021. No changes.
  5. arniebradfo revised this gist May 1, 2021. 3 changed files with 24 additions and 1 deletion.
    11 changes: 11 additions & 0 deletions app.tsx
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,11 @@
    import React from 'react'

    LazyCssComponent = React.lazy(() => import('./cssComponent'))
    AnotherLazyCssComponent = React.lazy(() => import('./anotherCssComponent'))

    export const App: React.FC = () =>(
    <React.Suspense fallback={<></>}>
    {condition && <LazyCssComponent/>}
    {!condition && <AnotherLazyCssComponent/>}
    </React.Suspense>
    )
    12 changes: 12 additions & 0 deletions cssComponent.tsx
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,12 @@
    import React from 'react'
    import { createUseDisableImportedStyles } from './useDisableImportedStyles'
    import './global-styles.css'

    const useDisableImportedStyles = createUseDisableImportedStyles()

    export const CssComponent: React.FC<{}> = () => {
    useDisableImportedStyles()
    return null
    }
    export default CssComponent

    2 changes: 1 addition & 1 deletion useDisableImportedStyles.tsx
    Original file line number Diff line number Diff line change
    @@ -52,7 +52,7 @@ type useDisableImportedStyles = () => void
    *
    */
    export const createUseDisableImportedStyles = (
    immediatelyUnloadStyle: boolean = false
    immediatelyUnloadStyle: boolean = true
    ): useDisableImportedStyles => {
    let localStyleSheet: StyleSheet
    return () => {
  6. arniebradfo created this gist May 1, 2021.
    85 changes: 85 additions & 0 deletions useDisableImportedStyles.tsx
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,85 @@
    import { useEffect } from 'react'

    // global list of all the StyleSheets that are touched in useDisableImportedStyles
    const switchableGlobalStyleSheets: StyleSheet[] = []

    // just to clarify what createUseDisableImportedStyles() returns
    type useDisableImportedStyles = () => void

    /**
    * Conditionally apply imported .css files
    * WARNING: This is pretty finicky. You must set this up exactly or there may be unintended consequences
    *
    * ## Conditions:
    *
    * 1. `createUseDisableImportedStyles` must called in global scope in the same tsx file as the imported css being targeted and the component to be lazy loaded
    * ```tsx
    * import React from 'react'
    * import { createUseDisableImportedStyles } from './useDisableImportedStyles'
    * import './global-styles.css'
    * const useDisableImportedStyles = createUseDisableImportedStyles()
    * export const CssComponent: React.FC<{}> = () => {
    * useDisableImportedStyles()
    * return null
    * }
    * export default CssComponent
    * ```
    *
    * 2. A component using this hook *should* be lazy loaded:
    * ```tsx
    * LazyCssComponent = React.lazy(() => import('./cssComponent'))
    * ...
    * <React.Suspense fallback={<></>}>
    * {condition && <LazyCssComponent/>}
    * </React.Suspense>
    * ```
    * - An exception to lazy loading might be using this in a single, normal, non-lazy component so styles are loaded on first render
    * - NOTE: the `InitialCssComponent` never needs to actually render, it just needs to be imported
    * - BUT: this will only work if there is **one single** .css file imported globally, otherwise, I don't know what would happen
    * ```tsx
    * import InitialCssComponent from './initialCssComponent'
    * LazyCssComponent = React.lazy(() => import('./cssComponent'))
    * ...
    * {false && <InitialCssComponent/>}
    * <React.Suspense fallback={<></>}>
    * {condition && <LazyCssComponent/>}
    * </React.Suspense>
    * ```
    *
    * @param {boolean} immediatelyUnloadStyle
    * if true: immediately unloads the StyleSheet when the component is unmounted
    * if false: waits to unloads the StyleSheet until another instance of useDisableImportedStyles is called. This avoids a flash of unstyled content
    *
    */
    export const createUseDisableImportedStyles = (
    immediatelyUnloadStyle: boolean = false
    ): useDisableImportedStyles => {
    let localStyleSheet: StyleSheet
    return () => {
    useEffect(() => {

    // if there are no stylesheets, you did something wrong...
    if (document.styleSheets.length < 1) return

    // set the localStyleSheet if this is the first time this instance of this useEffect is called
    if (localStyleSheet == null) {
    localStyleSheet = document.styleSheets[document.styleSheets.length - 1]
    switchableGlobalStyleSheets.push(localStyleSheet)
    }

    // if we are switching StyleSheets, disable all switchableGlobalStyleSheets
    if (!immediatelyUnloadStyle) {
    switchableGlobalStyleSheets.forEach(styleSheet => styleSheet.disabled = true)
    }

    // enable our StyleSheet!
    localStyleSheet.disabled = false

    // if we are NOT switching StyleSheets, disable this StyleSheet when the component is unmounted
    if (immediatelyUnloadStyle) return () => {
    if (localStyleSheet != null) localStyleSheet.disabled = true
    }

    })
    }
    }